paperless-ingester
v1.0.1
Published
Cross-platform CLI/TUI to upload matching PDF files from a folder tree to Paperless-ngx.
Readme
Paperless PDF Ingester (Cross-Platform)
Uploads all matching PDF files from a root folder and all subfolders to Paperless-ngx.
Scripts
paperless-ingest.mjs(plain CLI)paperless-ingest-ink.mjs(Ink TUI)
Requirements
- Windows, macOS, or Linux
- Node.js 18+ (Node 20+ recommended)
- Paperless API token (from your Paperless user settings)
Install deps
npm installInstall from npm
npm install -g paperless-ingesterCommands:
paperless-ingester(plain CLI)paperless-ingester-tui(Ink TUI)
Interactive Ink TUI
npm run tuiStartup flow:
- language selection dialog (English/Deutsch)
- step-by-step form with back navigation (Up arrow)
- review screen before upload starts
- then all labels/prompts/status text are shown in the selected language
The TUI then asks for:
- root path or mounted folder
- excluded paths (mini-list: Enter adds, empty Enter continues,
dremoves last,cclears) - regex filter
- profile name (optional, auto-loads URL+token if it exists)
- Paperless URL
- API token
- save-profile flag
- concurrency
- title mode
- dry-run flag
- follow-symlinks flag
How to define the Paperless path
Use the Paperless server URL, not a filesystem path.
Accepted inputs:
http://127.0.0.1:8000https://paperless.example.comhttps://paperless.example.com/apihttps://paperless.example.com/api/documents/post_document/
The ingester normalizes these to the correct base URL automatically.
After completion:
- press
eto export a full run report to your OS temp directory - press
q/Enter/Escto exit
You can point it at any accessible folder, for example:
/mnt/documents/run/media/<user>/<drive>- a network share mount point
Non-interactive CLI run
npm run cli -- \
--root /run/media/merres/MyNtfsDrive/Documents \
--filter invoice \
--paperless-url http://10.20.30.51:8000 \
--token "<YOUR_TOKEN>" \
--concurrency 2Useful options
--filter <regex>: regex over full file path- Example:
--filter '/(invoice|receipt)/i'
- Example:
--exclude-path <path>: skip a folder/path (repeat option for multiple excludes)- Example:
--exclude-path archive --exclude-path scans/private
- Example:
--exclude-file <path>: text file with one excluded path per line--retry-from <report>: retry only failed file paths from previous report JSON/log--profile <name>: load Paperless URL + token from saved profile--save-profile <name>: save current Paperless URL + token into profile--recipe <name>: load reusable scan recipe (root/filter/excludes/title mode/etc.)--save-recipe <name>: save current scan setup as reusable recipe--preflight: check server reachability + token auth before scanning--skip-known: duplicate protection (skip files uploaded successfully before)--known-cache <path>: cache file path for duplicate protection--incremental: only include files newer than last successful run for this root--full-scan: ignore incremental state even when--incrementalis set--incremental-state <path>: custom incremental state file--report-dir <path>: write structured.json+.logartifacts for each run--confirm-threshold <n>: require explicit confirmation for real uploads at/abovenfiles--dry-run: only list files that would be uploaded--title-mode relative: use relative path (without.pdf) as Paperless title--follow-symlinks: include symlinked directories
Profiles are stored at:
- Linux:
${XDG_CONFIG_HOME:-~/.config}/paperless-ingester/config.json - macOS:
~/Library/Application Support/paperless-ingester/config.json - Windows:
%APPDATA%\\paperless-ingester\\config.json - fallback:
.paperless-ingester/config.jsonin the current project folder
API token storage for profiles:
- always stored in OS keychain/credential store
- Linux: Secret Service (
secret-tool) - macOS: Keychain (
security) - Windows: Credential Manager (via PowerShell)
- profile config file stores metadata only (no plaintext token)
Runtime state files:
- duplicate cache default:
.paperless-ingester/known-cache.json - incremental state default:
.paperless-ingester/incremental-state.json - report artifacts default base:
.paperless-ingester/reports/(or your--report-dir)
Environment variables
export PAPERLESS_URL="http://10.20.30.51:8000"
export PAPERLESS_TOKEN="<YOUR_TOKEN>"
npm run cli -- --root /mnt/ntfs --filter receiptPaperless endpoint used
From your server schema (/api/schema/):
POST /api/documents/post_document/- multipart field
documentis required - auth header must be
Authorization: Token <token>
