Poznote provides a comprehensive RESTful API v1 for programmatic access to notes, folders, workspaces, tags, attachments, backups, settings, and more.
- Authentication
- Multi-User Mode
- Base URL
- Response Format
- HTTP Status Codes
- Interactive Documentation (Swagger)
- Notes
- Note Sharing
- Folder Sharing
- Backlinks
- Folders
- Trash
- Workspaces
- Tags
- Attachments
- Backups
- Export (Legacy)
- Settings
- System
- Git Sync
- User Profile
- Admin (User Management)
- Public / Shared Tasks
- Health Check
All API endpoints (except public ones) require authentication. Poznote supports HTTP Basic Authentication, OIDC Bearer JWT tokens, and the internal Bearer token used by the MCP server.
curl -u 'username:password' http://YOUR_SERVER/api/v1/notesUse the current password of the profile you authenticate with. Default local passwords are admin for administrators and user for standard users until they are changed in the Poznote UI.
OIDC Bearer JWT authentication is available when OIDC is enabled. Poznote validates the token signature with the provider JWKS, checks issuer, expiration, and audience, then maps the token claims to a Poznote profile using the same OIDC linking rules as interactive login (sub, then preferred_username, then email). Group and user allowlists, disabled profiles, and auto-create settings are also enforced.
curl -H "Authorization: Bearer $OIDC_ACCESS_TOKEN" -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notesFor OIDC Bearer JWT requests, data endpoints default to the profile linked to the token subject when X-User-ID is omitted. Admin JWTs may still include X-User-ID to access another profile.
By default, the accepted JWT aud claim is the configured OIDC Client ID. If your identity provider issues API access tokens with a dedicated audience, set API JWT audience in Settings > Admin Tools > OIDC / SSO. Multiple accepted audiences can be separated with commas.
| Level | Description | Used by |
|---|---|---|
| No auth | No credentials needed | GET /api/v1/users/profiles, GET /api_health.php, Public tasks |
| User auth | Valid credentials, no X-User-ID needed |
/api/v1/users/me, /api/v1/system/*, /api/v1/shared/* |
| Data auth | Valid credentials; X-User-ID required for Basic/service token, optional for OIDC JWT own profile |
All user data endpoints (notes, folders, tags, etc.) |
| Admin auth | Admin credentials, no X-User-ID needed |
/api/v1/admin/*, /api/v1/users/lookup/* |
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.), Basic Auth and internal service-token requests must include the X-User-ID header. OIDC Bearer JWT requests use the token-linked profile by default and only need X-User-ID when an admin token targets another profile.
Account-access grants configured in the web admin UI only apply to interactive browser sessions after login account selection. They do not allow non-admin API credentials to use X-User-ID for another profile. API access to another user's data requires administrator credentials or the internal service token.
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 - User profile endpoints:
/api/v1/users/me,/api/v1/users/me/password,/api/v1/users/me/password-status - System endpoints:
/api/v1/system/*(version, updates, i18n) - Shared endpoints:
/api/v1/shared,/api/v1/shared/with-me
Use GET /api/v1/users/profiles to list available user profiles and their IDs.
/api/v1
All endpoints in this document are relative to this base URL unless otherwise noted (legacy endpoints use full paths).
All endpoints return JSON. Successful responses typically follow this structure:
{
"success": true,
"data": { ... }
}Error responses:
{
"success": false,
"error": "Error description"
}| Code | Description |
|---|---|
200 |
OK – Request succeeded |
201 |
Created – Resource created successfully |
204 |
No Content – CORS preflight |
400 |
Bad Request – Invalid parameters |
401 |
Unauthorized – Missing or invalid credentials |
403 |
Forbidden – Insufficient permissions |
404 |
Not Found – Resource does not exist |
405 |
Method Not Allowed |
409 |
Conflict – Resource already exists |
413 |
Payload Too Large |
500 |
Internal Server Error |
Access the Swagger UI directly from Poznote at Settings > API Documentation to browse all endpoints, view request/response schemas, and test API calls interactively.
GET /notes
List all notes for a user with optional filtering and sorting.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
workspace |
string | Filter by workspace name |
folder |
string | Filter by folder name |
folder_id |
integer | Filter by folder ID |
tag |
string | Filter by tag |
search |
string | Search in heading and content |
created_from |
date | Filter notes created on or after this date (YYYY-MM-DD) |
created_to |
date | Filter notes created on or before this date (YYYY-MM-DD) |
favorite |
boolean | Filter favorites only |
sort |
string | Sort order: updated_desc, created_desc, heading_asc |
get_folders |
boolean | Include folder information |
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notesFilter notes by workspace, folder, and tag:
curl -u 'username:password' -H "X-User-ID: 1" \
"http://YOUR_SERVER/api/v1/notes?workspace=Personal&folder=Projects&tag=important"Filter notes by creation date:
curl -u 'username:password' -H "X-User-ID: 1" \
"http://YOUR_SERVER/api/v1/notes?created_from=2026-01-01&created_to=2026-01-31"GET /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 /notes/{id}
Get a specific note by ID, including its content.
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notes/123GET /notes/resolve
Resolve a note by title (reference) inside a workspace.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
reference |
string | Note title to search for |
workspace |
string | Workspace to search in |
curl -u 'username:password' -H "X-User-ID: 1" \
"http://YOUR_SERVER/api/v1/notes/resolve?reference=My+Note&workspace=Personal"GET /notes/search
Search notes by heading or content.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
q |
string | Search query |
created_from |
date | Filter notes created on or after this date (YYYY-MM-DD) |
created_to |
date | Filter notes created on or before this date (YYYY-MM-DD) |
curl -u 'username:password' -H "X-User-ID: 1" \
"http://YOUR_SERVER/api/v1/notes/search?q=docker&created_from=2026-01-01&created_to=2026-01-31"POST /notes
Create a new note with title, content, tags, folder and workspace.
Request Body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
heading |
string | Yes | Note title |
content |
string | No | Note content (HTML or Markdown) |
entry |
string | No | Alternative field for content |
tags |
string | No | Comma-separated tags |
folder_id |
integer | No | Target folder ID |
folder |
string | No | Target folder name |
workspace |
string | No | Target workspace |
type |
string | No | Note type: note (HTML), markdown, tasklist |
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/notesPATCH /notes/{id}
Update an existing note by ID. Only include fields you want to modify.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
heading |
string | Updated title |
content |
string | Updated content |
tags |
string | Updated comma-separated tags |
folder_id |
integer | Move to folder |
workspace |
string | Move to workspace |
git_push |
boolean | Trigger Git sync after update |
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 /notes/{id}
Move a note to trash (soft delete by default).
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
permanent |
boolean | If true, permanently delete (bypass trash) |
Move to trash:
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notes/123Permanently delete:
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \
"http://YOUR_SERVER/api/v1/notes/123?permanent=true"POST /notes/{id}/restore
Restore a note from trash.
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notes/123/restorePOST /notes/{id}/duplicate
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/duplicatePOST /notes/{id}/create-template
Create a reusable template from an existing note.
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notes/123/create-templatePOST /notes/{id}/convert
Convert a note between Markdown and HTML formats.
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notes/123/convertPUT /notes/{id}/tags
Replace all tags on a note.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
tags |
string | Comma-separated tag list |
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/tagsPOST /notes/{id}/favorite
Toggle favorite status for a note.
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notes/123/favoritePOST /notes/{id}/folder
Move a note to a different folder.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
folder_id |
integer | Target folder ID |
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/folderPOST /notes/{id}/remove-folder
Remove a note from its folder (move to root).
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notes/123/remove-folderPOST /notes/{id}/beacon
Emergency save via sendBeacon API. Accepts FormData instead of JSON. Used internally by the browser when navigating away or closing the page.
GET /notes/{id}/share
Check if a note is shared and get share details.
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notes/123/sharePOST /notes/{id}/share
Create a public share link for a note.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
theme |
string | Display theme: light, dark, or black |
indexable |
boolean | Allow search engine indexing |
password |
string | Optional password protection |
custom_token |
string | Custom URL token (slug) |
access_mode |
string | Access mode for the share |
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/sharePATCH /notes/{id}/share
Update share settings on an existing share.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
theme |
string | Display theme |
indexable |
boolean | Allow indexing |
password |
string | Password protection |
custom_token |
string | Custom URL token |
access_mode |
string | Access mode |
allowed_users |
array | User IDs with access |
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/shareDELETE /notes/{id}/share
Remove sharing access for a note.
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notes/123/shareGET /shared
Get list of all shared notes and folders. Does not require the X-User-ID header.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
workspace |
string | Filter by workspace |
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/sharedGET /shared/with-me
List notes and folders shared with the current user by other users.
curl -u 'username:password' \
http://YOUR_SERVER/api/v1/shared/with-meGET /folders/{id}/share
Check if a folder is shared.
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/folders/5/sharePOST /folders/{id}/share
Share a folder. All notes in the folder will also be shared.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
theme |
string | Display theme: light, dark, or black |
indexable |
integer | Allow indexing (0 or 1) |
password |
string | Optional password protection |
custom_token |
string | Custom URL slug |
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/sharePATCH /folders/{id}/share
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
indexable |
integer | Allow indexing |
password |
string | Password protection |
custom_token |
string | Custom token |
allowed_users |
array | User IDs with access |
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/shareDELETE /folders/{id}/share
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/shareGET /notes/{id}/backlinks
Get all notes that link to this note. Supports HTML links, URL parameters, and wiki-link syntax [[Note Title]].
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notes/123/backlinksGET /folders
List all folders in a workspace.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
workspace |
string | Filter by workspace |
tree |
boolean | Return hierarchical tree structure |
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 /folders/{id}
Get details of a specific folder.
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/folders/12GET /folders/counts
Get note counts for all folders.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
workspace |
string | Filter by workspace |
curl -u 'username:password' -H "X-User-ID: 1" \
"http://YOUR_SERVER/api/v1/folders/counts?workspace=Personal"GET /folders/suggested
Get a list of suggested folders based on usage patterns.
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/folders/suggestedGET /folders/{id}/path
Get the full breadcrumb path for a folder.
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/folders/12/pathGET /folders/{id}/notes
Get the number of notes in a folder (recursive).
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/folders/12/notesPOST /folders
Create a new folder.
Request Body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Folder name |
workspace |
string | No | Target workspace |
parent_id |
integer | No | Parent folder ID (for subfolders) |
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/foldersPATCH /folders/{id}
Rename an existing folder.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
name |
string | New folder name |
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/12POST /folders/{id}/move
Move folder to a different parent or workspace.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
parent_id |
integer|null | New parent folder ID (null for root) |
target_workspace |
string | Target workspace (for cross-workspace move) |
Move to another 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:
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:
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/movePOST /folders/move-files
Move all files from one folder to another.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
source_folder_id |
integer | Source folder ID |
target_folder_id |
integer | Target folder ID |
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
-H "Content-Type: application/json" \
-d '{"source_folder_id": 10, "target_folder_id": 20}' \
http://YOUR_SERVER/api/v1/folders/move-filesPOST /folders/kanban-structure
Create a Kanban board folder structure.
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
-H "Content-Type: application/json" \
-d '{"workspace": "Personal", "name": "Project Board"}' \
http://YOUR_SERVER/api/v1/folders/kanban-structurePUT /folders/{id}/icon
Set a custom icon for a folder.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
icon |
string | Icon class name (e.g. fa-folder-open) |
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/iconPOST /folders/{id}/empty
Move all notes in a folder to trash.
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/folders/12/emptyDELETE /folders/{id}
Delete a folder.
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/folders/12GET /trash
Get all notes in trash.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
workspace |
string | Filter by workspace |
search |
string | Search in trashed notes |
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"DELETE /trash
Permanently delete all notes in trash.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
workspace |
string | Only empty trash for a specific workspace |
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/trashDELETE /trash/{id}
Delete a specific note permanently from trash.
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/trash/123GET /workspaces
Get all workspaces.
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/workspacesPOST /workspaces
Request Body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Workspace name |
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
-H "Content-Type: application/json" \
-d '{"name": "MyProject"}' \
http://YOUR_SERVER/api/v1/workspacesPATCH /workspaces/{name}
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
new_name |
string | New workspace name |
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 /workspaces/{name}
Delete a workspace and all its contents.
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/workspaces/OldWorkspaceGET /tags
Get all unique tags.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
workspace |
string | Filter by workspace |
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"GET /notes/{noteId}/attachments
Get all attachments for a specific note.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
workspace |
string | Workspace context |
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notes/123/attachmentsPOST /notes/{noteId}/attachments
Upload a file attachment to a note.
Request Body (multipart/form-data):
| Field | Type | Description |
|---|---|---|
file |
file | The file to upload |
workspace |
string | Workspace context |
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
-F "file=@/path/to/file.pdf" \
http://YOUR_SERVER/api/v1/notes/123/attachmentsGET /notes/{noteId}/attachments/{attachmentId}
Download a specific attachment. This endpoint also supports unauthenticated access for publicly shared notes using the token query parameter.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
workspace |
string | Workspace context |
token |
string | Public share token (for shared notes) |
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notes/123/attachments/456 \
-o downloaded-file.pdfDELETE /notes/{noteId}/attachments/{attachmentId}
Delete an attachment from a note.
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/notes/123/attachments/456GET /backups
Get a list of all backup files with sizes and timestamps.
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/backupsPOST /backups
Create a complete backup ZIP containing database, all notes, and attachments.
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/backupsGET /backups/{filename}
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.zipPOST /backups/upload
Upload a local backup ZIP to the server's backup directory. The file is stored with a standard timestamped name and its filename is returned for use with the restore endpoint.
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
-F "file=@demo.zip" \
http://YOUR_SERVER/api/v1/backups/uploadResponse (201):
{
"success": true,
"filename": "poznote_backup_2025-01-05_12-00-00.zip",
"size": 102400,
"size_mb": 0.1,
"restore_url": "/api/v1/backups/poznote_backup_2025-01-05_12-00-00.zip/restore",
"download_url": "/api/v1/backups/poznote_backup_2025-01-05_12-00-00.zip"
}POST /backups/{filename}/restore
Restore a backup file. This 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 /backups/{filename}
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.zipThese endpoints use legacy URL paths (not under /api/v1) and are primarily used for file downloads.
Export a single note in various formats.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
integer | Note ID (required) |
format |
string | html, markdown, or json |
type |
string | Note type hint |
disposition |
string | attachment (download) or inline (display) |
curl -u 'username:password' -H "X-User-ID: 1" \
"http://YOUR_SERVER/api_export_note.php?id=123&format=html" \
-o exported-note.htmlExport a folder as ZIP.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
folder_id |
integer | Folder ID |
workspace |
string | Workspace filter |
curl -u 'username:password' -H "X-User-ID: 1" \
"http://YOUR_SERVER/api_export_folder.php?folder_id=123" \
-o folder-export.zipExport all notes preserving folder hierarchy.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
workspace |
string | Workspace filter |
curl -u 'username:password' -H "X-User-ID: 1" \
"http://YOUR_SERVER/api_export_structured.php?workspace=Personal" \
-o structured-export.zipExport all note files as ZIP.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
workspace |
string | Workspace filter (optional) |
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api_export_entries.php \
-o all-notes.zipExport all attachments as ZIP with metadata.
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api_export_attachments.php \
-o all-attachments.zipDownload a note file with proper headers and inline styling.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
integer | Note ID (required) |
type |
string | Note type hint |
curl -u 'username:password' -H "X-User-ID: 1" \
"http://YOUR_SERVER/api_download_note.php?id=123" \
-o note.htmlGET /settings
Get setting values in one request. Use keys to return only specific settings; omit it to return all user settings, plus global settings for admins.
curl -u 'username:password' -H "X-User-ID: 1" \
"http://YOUR_SERVER/api/v1/settings?keys=language,note_age_filter_days"GET /settings/{key}
Get a setting value (user-level or global).
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/settings/languagePUT /settings/{key}
Set a setting value. Global settings require admin privileges.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
value |
mixed | The 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/languageGlobal settings (admin only):
login_display_namecustom_css_path(read-only via this API — usePOST /api_upload_css.phpto upload a file orDELETE /api_upload_css.phpto remove it)git_sync_enabledimport_max_individual_filesimport_max_zip_files
System endpoints do not require the X-User-ID header.
GET /system/version
Get current version and system information.
curl -u 'username:password' \
http://YOUR_SERVER/api/v1/system/versionGET /system/updates
Check if a newer version is available on GitHub.
curl -u 'username:password' \
http://YOUR_SERVER/api/v1/system/updatesGET /system/i18n
Get translation/localization strings.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
lang |
string | Language code (e.g. fr, en) |
curl -u 'username:password' \
http://YOUR_SERVER/api/v1/system/i18nGit sync endpoints allow managing synchronization with GitHub or Forgejo repositories. Each user configures their own repository independently.
Both /git-sync/ and /github-sync/ prefixes are supported (the latter is a legacy alias).
GET /git-sync/status
Get Git sync configuration and status.
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/git-sync/statusPOST /git-sync/test
Test the Git connection and credentials.
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/git-sync/testPOST /git-sync/push
Push notes to the configured Git repository.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
workspace |
string | Workspace to push (optional, pushes all if omitted) |
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/git-sync/pushPush a specific workspace:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
-H "Content-Type: application/json" \
-d '{"workspace": "Personal"}' \
http://YOUR_SERVER/api/v1/git-sync/pushPOST /git-sync/pull
Pull notes from the configured Git repository.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
workspace |
string | Workspace to pull (optional, pulls all if omitted) |
curl -X POST -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/git-sync/pullGET /git-sync/progress
Get the current sync progress from the session.
curl -u 'username:password' -H "X-User-ID: 1" \
http://YOUR_SERVER/api/v1/git-sync/progressPUT /git-sync/config
Save per-user Git sync configuration.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
provider |
string | github or forgejo |
repo |
string | Repository in owner/repo format |
token |
string | Access token (PAT) |
branch |
string | Git branch (default: main) |
api_base |
string | API base URL (Forgejo only) |
author_name |
string | Commit author name |
author_email |
string | Commit author email |
curl -X PUT -u 'username:password' -H "X-User-ID: 1" \
-H "Content-Type: application/json" \
-d '{
"provider": "github",
"repo": "username/my-notes",
"token": "ghp_xxxxxxxxxxxx",
"branch": "main",
"author_name": "John",
"author_email": "john@example.com"
}' \
http://YOUR_SERVER/api/v1/git-sync/configGET /users/profiles
Get list of active user profiles for the login selector. No authentication required.
curl http://YOUR_SERVER/api/v1/users/profilesGET /users/me
Get the current authenticated user's profile.
curl -u 'username:password' \
http://YOUR_SERVER/api/v1/users/mePOST /users/me/password
Change the current user's password.
Request Body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
old_password |
string | Yes | Current password |
new_password |
string | Yes | New password |
curl -X POST -u 'username:password' \
-H "Content-Type: application/json" \
-d '{"old_password": "current", "new_password": "newpass"}' \
http://YOUR_SERVER/api/v1/users/me/passwordGET /users/me/password-status
Check whether the current user has a custom password or is using the .env fallback.
curl -u 'username:password' \
http://YOUR_SERVER/api/v1/users/me/password-statusAdmin endpoints require administrator credentials and do not require the X-User-ID header.
GET /admin/users
Get detailed list of all users with storage info.
curl -u 'username:password' \
http://YOUR_SERVER/api/v1/admin/usersGET /admin/users/{id}
Get detailed information about a user.
curl -u 'username:password' \
http://YOUR_SERVER/api/v1/admin/users/1POST /admin/users
Create a new user profile.
Request Body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
username |
string | Yes | Username |
email |
string | No | Email address |
curl -X POST -u 'username:password' \
-H "Content-Type: application/json" \
-d '{"username": "newuser"}' \
http://YOUR_SERVER/api/v1/admin/usersPATCH /admin/users/{id}
Update user properties.
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
username |
string | New username |
active |
boolean | Active status |
is_admin |
boolean | Admin privileges |
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 /admin/users/{id}
Delete a user profile.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
delete_data |
boolean | If true, also delete all user data |
Delete profile only:
curl -X DELETE -u 'username:password' \
http://YOUR_SERVER/api/v1/admin/users/2Delete profile and all data:
curl -X DELETE -u 'username:password' \
"http://YOUR_SERVER/api/v1/admin/users/2?delete_data=true"POST /admin/users/{id}/reset-password
Reset or set a custom password for a user.
curl -X POST -u 'username:password' \
-H "Content-Type: application/json" \
-d '{"password": "new-password"}' \
http://YOUR_SERVER/api/v1/admin/users/2/reset-passwordGET /admin/users/{id}/password-status
Check whether a user has a custom password or is using the .env fallback.
curl -u 'username:password' \
http://YOUR_SERVER/api/v1/admin/users/2/password-statusGET /users/lookup/{username}
Get user ID by username. Admin only. Used by backup scripts.
curl -u 'username:password' \
http://YOUR_SERVER/api/v1/users/lookup/NinaGET /admin/stats
Get aggregated statistics for all users.
curl -u 'username:password' \
http://YOUR_SERVER/api/v1/admin/statsPOST /admin/repair
Scan and rebuild the master database registry.
curl -X POST -u 'username:password' \
http://YOUR_SERVER/api/v1/admin/repairThese endpoints manage interactive tasks on publicly shared notes. They use a token query parameter for authentication instead of HTTP Basic Auth.
PATCH /public/tasks/{id}
Update a task's status or text on a shared note.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
token |
string | Public share token |
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
completed |
boolean | Task completion status |
text |
string | Task text |
curl -X PATCH \
-H "Content-Type: application/json" \
-d '{"completed": true}' \
"http://YOUR_SERVER/api/v1/public/tasks/0?token=abc123"POST /public/tasks
Add a new task to a shared task list.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
token |
string | Public share token |
Request Body (JSON):
| Field | Type | Description |
|---|---|---|
text |
string | Task text |
curl -X POST \
-H "Content-Type: application/json" \
-d '{"text": "New task item"}' \
"http://YOUR_SERVER/api/v1/public/tasks?token=abc123"DELETE /public/tasks/{id}
Delete a task from a shared task list.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
token |
string | Public share token |
curl -X DELETE \
"http://YOUR_SERVER/api/v1/public/tasks/0?token=abc123"GET /api_health.php
Health check endpoint. No authentication required. Returns service status, name, and version.
curl http://YOUR_SERVER/api_health.phpResponse:
{
"status": "ok",
"service": "poznote",
"version": "x.x.x"
}| Method | Endpoint | Description |
|---|---|---|
GET |
/notes |
List notes |
GET |
/notes/with-attachments |
List notes with attachments |
GET |
/notes/resolve |
Resolve note by reference |
GET |
/notes/search |
Search notes |
GET |
/notes/{id} |
Get note |
POST |
/notes |
Create note |
PATCH |
/notes/{id} |
Update note |
DELETE |
/notes/{id} |
Delete note |
POST |
/notes/{id}/restore |
Restore from trash |
POST |
/notes/{id}/duplicate |
Duplicate note |
POST |
/notes/{id}/create-template |
Create template |
POST |
/notes/{id}/convert |
Convert type |
POST |
/notes/{id}/beacon |
Emergency save |
PUT |
/notes/{id}/tags |
Update tags |
POST |
/notes/{id}/favorite |
Toggle favorite |
POST |
/notes/{id}/folder |
Move to folder |
POST |
/notes/{id}/remove-folder |
Remove from folder |
| Method | Endpoint | Description |
|---|---|---|
GET |
/notes/{id}/share |
Get share status |
POST |
/notes/{id}/share |
Create share link |
PATCH |
/notes/{id}/share |
Update share settings |
DELETE |
/notes/{id}/share |
Revoke share |
GET |
/shared |
List shared notes |
GET |
/shared/with-me |
Shared with me |
| Method | Endpoint | Description |
|---|---|---|
GET |
/notes/{id}/backlinks |
Get backlinks |
| Method | Endpoint | Description |
|---|---|---|
GET |
/folders |
List folders |
GET |
/folders/counts |
Folder counts |
GET |
/folders/suggested |
Suggested folders |
GET |
/folders/{id} |
Get folder |
GET |
/folders/{id}/notes |
Note count |
GET |
/folders/{id}/path |
Folder path |
POST |
/folders |
Create folder |
PATCH |
/folders/{id} |
Rename folder |
DELETE |
/folders/{id} |
Delete folder |
POST |
/folders/{id}/move |
Move folder |
POST |
/folders/{id}/empty |
Empty folder |
PUT |
/folders/{id}/icon |
Update icon |
POST |
/folders/move-files |
Move files |
POST |
/folders/kanban-structure |
Create Kanban |
| Method | Endpoint | Description |
|---|---|---|
GET |
/folders/{id}/share |
Get share status |
POST |
/folders/{id}/share |
Create share link |
PATCH |
/folders/{id}/share |
Update share |
DELETE |
/folders/{id}/share |
Revoke share |
| Method | Endpoint | Description |
|---|---|---|
GET |
/trash |
List trash |
DELETE |
/trash |
Empty trash |
DELETE |
/trash/{id} |
Delete from trash |
| Method | Endpoint | Description |
|---|---|---|
GET |
/workspaces |
List workspaces |
POST |
/workspaces |
Create workspace |
PATCH |
/workspaces/{name} |
Rename workspace |
DELETE |
/workspaces/{name} |
Delete workspace |
| Method | Endpoint | Description |
|---|---|---|
GET |
/tags |
List tags |
| Method | Endpoint | Description |
|---|---|---|
GET |
/notes/{noteId}/attachments |
List attachments |
POST |
/notes/{noteId}/attachments |
Upload attachment |
GET |
/notes/{noteId}/attachments/{id} |
Download attachment |
DELETE |
/notes/{noteId}/attachments/{id} |
Delete attachment |
| Method | Endpoint | Description |
|---|---|---|
GET |
/backups |
List backups |
POST |
/backups |
Create backup |
GET |
/backups/{filename} |
Download backup |
POST |
/backups/upload |
Upload backup ZIP |
POST |
/backups/{filename}/restore |
Restore backup |
DELETE |
/backups/{filename} |
Delete backup |
| Method | Endpoint | Description |
|---|---|---|
GET |
/settings |
Get settings |
GET |
/settings/{key} |
Get setting |
PUT |
/settings/{key} |
Update setting |
| Method | Endpoint | Description |
|---|---|---|
GET |
/system/version |
Version info |
GET |
/system/updates |
Check updates |
GET |
/system/i18n |
Translations |
| Method | Endpoint | Description |
|---|---|---|
GET |
/git-sync/status |
Sync status |
POST |
/git-sync/test |
Test connection |
POST |
/git-sync/push |
Push notes |
POST |
/git-sync/pull |
Pull notes |
GET |
/git-sync/progress |
Sync progress |
PUT |
/git-sync/config |
Save config |
| Method | Endpoint | Description |
|---|---|---|
GET |
/users/profiles |
List profiles (public) |
GET |
/users/me |
Current user |
POST |
/users/me/password |
Change password |
GET |
/users/me/password-status |
Password status |
GET |
/users/lookup/{username} |
Lookup by name |
| Method | Endpoint | Description |
|---|---|---|
GET |
/admin/users |
List users |
GET |
/admin/users/{id} |
Get user |
POST |
/admin/users |
Create user |
PATCH |
/admin/users/{id} |
Update user |
DELETE |
/admin/users/{id} |
Delete user |
POST |
/admin/users/{id}/reset-password |
Reset password |
GET |
/admin/users/{id}/password-status |
Password status |
GET |
/admin/stats |
System stats |
POST |
/admin/repair |
Repair database |
| Method | Endpoint | Description |
|---|---|---|
PATCH |
/public/tasks/{id} |
Update task |
POST |
/public/tasks |
Add task |
DELETE |
/public/tasks/{id} |
Delete task |