Everything the interface does is a REST call, and the interface uses the same API you would. There is also a command-line tool for a few things that suit a terminal better.
The authoritative reference is in the app, at /api-docs/rest and its sibling sections. It is generated from the same catalogue the running build uses, so it cannot describe endpoints your version does not have. This guide orients you and then sends you there — it deliberately does not duplicate the endpoint tables, because a copy in a document goes stale and a wrong endpoint list is worse than none.
The seven faces
The app exposes more than one API, because different tools expect different shapes.
| In the app | What it is | Use it for |
|---|---|---|
| /api-docs/rest | The main JSON API | Anything the interface can do |
| /api-docs/s3 | S3-compatible gateway | rclone, aws CLI, boto3, any S3 SDK |
| /api-docs/sab | SABnzbd-compatible shim | Sonarr, Radarr and friends |
| /api-docs/newznab | Newznab indexer shim | The same, for searching |
| /api-docs/datasets | Dataset access | Hugging Face datasets, fsspec |
| /api-docs/portal | HMAC-signed provisioning | A billing portal granting access by SKU |
| /api-docs/cli | Command-line reference | Terminal work |
Each page carries auth details and working recipes with your live endpoint filled in.
Getting started with the REST API
Base address: http://127.0.0.1:8386/api
Authentication: an X-API-Key header. Your key is in Settings → Advanced →
Security, where it can be revealed and rotated. /api/health needs no key, which
makes it the right thing for a monitoring check.
KEY=<your api key>
BASE=http://127.0.0.1:8386/api
curl "$BASE/health"
curl -H "X-API-Key: $KEY" "$BASE/shares"
Publishing a folder
curl -X POST "$BASE/uploads" \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"path": "/data/my-folder",
"newsgroup": "alt.binaries.boneless",
"access_type": "public",
"auto_upload": true}'
That is the one-call version. There is also a stepwise route — create the folder, index it, upload it, publish it — when you want to inspect or gate between stages. Both are documented at /api-docs/rest.
Importing and downloading a share
# import
curl -X POST "$BASE/shares/import" \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"share_link": "usn://..."}'
# download a subfolder of it
curl -X POST "$BASE/shares/$SID/download" \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"output_path": "/data/downloads", "paths": ["Season.01/"]}'
# watch it
curl -H "X-API-Key: $KEY" "$BASE/shares/$SID/summary"
Omit paths and pass "full_share": true for everything.
Long operations are asynchronous
Publishing, importing, downloading and verifying return immediately with a task identifier. Poll for progress rather than holding a request open:
| Poll | For |
|---|---|
GET /api/queue/status |
Everything currently running |
GET /api/shares/<id>/summary |
One share's download |
GET /api/shares/<id>/import-status |
An import in progress |
GET /api/folders/<id>/timeline |
A publish, stage by stage |
A sensible script starts the work, then polls the queue until it is done. Do not poll in a tight loop — a second or two between checks is plenty, and the numbers do not move faster than that.
The CLI
python -m refactored.cli --db <path-to-usenet.db> <command>
Best at three things.
Consuming shares, which scripts well:
python -m refactored.cli --db "$DB" import-share-link 'usn://...'
python -m refactored.cli --db "$DB" download <share-id> /out
python -m refactored.cli --db "$DB" download-subfolder <share-id> Season.01 /out
Checking state: status, folder-status <id>, pause, resume.
Key management, which is the part with no equivalent elsewhere:
| Command | Does |
|---|---|
init |
Create the owner identity |
security-status |
Report how the owner key is stored |
harden-master-key --to-file <path> |
Move the master key out of the database |
purge-db-master-key |
Remove the in-database copy |
machine-bind-master-key |
Wrap the key so it only opens on this host |
These matter on a machine other people can reach. By default the master key is in the database; hardening moves it out, and machine-binding makes a stolen copy useless elsewhere. Read /api-docs/cli before running them — done in the wrong order you can lock yourself out of your own folders.
Publishing from the CLI is deprecated. upload and publish exit and tell you
to use the API instead. That is deliberate: publishing has to run inside the
background service to be resumable and checkpointed, and a command-line process that
owns it cannot be.
Common jobs
Monitoring. Poll GET /api/health — no key needed. It reports the service, the
worker and the provider connection separately, so an alert can say which is
unhealthy.
Publish on a schedule. POST /api/uploads with auto_upload: true, then poll
/api/queue/status. Remember that re-publishing an existing folder mints a new
link — if consumers use a stable address, hand them something you control that
redirects, not the raw link.
Mirror a share to disk nightly. POST /api/shares/<id>/download into the same
destination each time. Files already correct are checked against the published hashes
and reused, so a repeat run transfers only what changed.
Verify on a schedule. POST /api/shares/<id>/verify-and-repair, with
{"mode": "count"} for a quick pass or {"mode": "sha256"} for a full one. It
repairs what it finds. See Verify and repair.
Notes that save time
Rotate the API key if it has been anywhere it should not. Settings → Advanced → Security → Rotate. Anything holding the old key stops working, which is the point.
Bind to 127.0.0.1 unless you mean otherwise. Exposing the API to a network
without also turning on the login gate (USENET_API_AUTH_ENABLE=1) leaves it open
to everyone who can route to the port.
One download runs at a time. A script that starts several gets one running and the rest queued. That is not an error, and the queue endpoint shows it.
A share link contains a key. Treat links in scripts, logs and CI output the way you would treat credentials. A public share's link is its key.
Next
- /api-docs/rest in the app — the reference itself
- /api-docs/cli — every command, with arguments
- S3 object storage — usually the better fit for reading data programmatically