Feeding a few hundred PDFs to Paperless without losing my mind
Paperless-ngx is the closest thing to a magic filing cabinet you can self-host. It OCRs scanned paperwork, guesses dates and correspondents, and makes the whole pile searchable. You can just dump files into its consume folder, but with a few hundred documents I wanted titles, types and tags set on the way in, not fixed one at a time afterwards.
A list beats a folder
So I built a tab-separated list: path, title, document type, correspondent, tags. A small script reads it, creates any missing tags and types through the REST API, then uploads each file to /api/documents/post_document/ with everything attached. Bonus: the list doubles as a record of what went in and what got skipped on purpose.
curl -H "Authorization: Token $TOKEN" \
-F document=@"$file" -F title="$title" \
-F document_type="$type_id" -F tags="$tag_id" \
"$PAPERLESS/api/documents/post_document/"Bash, you sneaky thing
Here's one that bit me: IFS=$'\t' read treats tab as whitespace, so two tabs in a row collapse into one and every column after an empty field slides left. I noticed when a document showed up with a person's name as its document type. The fix was gloriously dumb: a - placeholder for "empty" in the list.
When "latest" means "broken"
PDFs and images imported perfectly. Every Word and Excel file failed with a 404. Paperless hands Office files to Apache Tika for conversion, and that container was riding the latest tag, which had just jumped to a new major version that dropped an endpoint Paperless relies on. Pinning Tika to the previous release fixed it on the spot.
Pin the versions of helper containers that another app depends on. "Latest" upgrades whenever the container is recreated, whether or not its dependents are ready.
Private by default
Every document belongs to one user and isn't shared unless I say so. Paperless permissions are per document, so pick your defaults before the import, not after a few hundred files have landed.