- The Setup: Why Headless Transfers
- Running the Server Without a Screen
- Sending Files from the Command Line
- The Device Registry and Device Names
- Wiring It Into a Cron Job
- Where the CLI Falls Short
The Setup: Why Headless Transfers
A common setup: a Linux box with no monitor that collects logs or backups, and a desktop or phone where you actually want those files. SSH and scp work, but you manage keys and addresses for every machine. The OpenDrop desktop app has a command line built in, so the same box can serve files and push them on a schedule without ever opening a window.
The CLI ships with the Windows and Linux desktop builds. Running opendrop with no arguments opens the app. Any subcommand skips the window and runs in the terminal. On Linux, opendrop install-cli links the command into /usr/local/bin. The Windows installer has an option to add it to PATH.
The commands this post uses:
opendrop serve: run OpenDrop headless. Add--backgroundto detach, and useopendrop stopto shut it down.opendrop upload <files>: copy files or folders into this computer's OpenDrop storage. Add-d "Device Name"to send them to another device (Pro).opendrop devices: list your devices that are online right now (Pro).opendrop status: show whether the server is running and connected.opendrop sign-in: sign in to your OpenDrop account from the terminal.
Commands that only touch this computer work on Free. Anything that reaches another device (the -d flag, devices, shared folders) needs OpenDrop Pro, because Pro is what links your devices through one account. opendrop help <command> prints the flags and examples for any command.
Running the Server Without a Screen
SSH into the box and run opendrop serve. It starts the local server on port 8000, listening on all interfaces, then connects out to OpenDrop's own encrypted relay so your devices can reach it from other networks. There is nothing extra to install and no port to forward.
The output looks roughly like this, with real values replaced by placeholders:
OpenDrop server starting on 0.0.0.0:8000...
Not signed in (use 'opendrop sign-in' to authenticate)
LAN IP: 192.168.1.20
Server running on https://127.0.0.1:8000
Waiting for tunnel... (Press Ctrl+C to stop)
Tunnel connected (<relay>)
URL: <connection URL>
Password: <pairing password>
[QR code]
"Tunnel" here means the outbound connection to OpenDrop's relay. It is not a third-party tunnel you have to download.
The password and QR code pair a phone with this computer. Scan the QR code in the OpenDrop app and the box shows up on your phone. That part works on Free with no account: each phone pairs with one computer by scanning its QR code. Treat the QR code like a password. Anyone who scans it can pair with the box, so keep that output out of shared logs and screenshots.
A foreground serve stops when your SSH session closes. Three ways to keep it running:
opendrop serve --backgrounddetaches, prints the connection info and returns you to the prompt. Its log, which also holds the pairing password and QR code, goes toserve.login the OpenDrop config folder (~/.config/opendrop/on Linux). Stop it withopendrop stop.- Run it inside
tmuxorscreenif you want to watch the output. - For a box that should always be reachable, make it a systemd service so it starts at boot and restarts if it exits.
A minimal user service looks like this:
[Unit]
Description=OpenDrop headless server
[Service]
ExecStart=/usr/local/bin/opendrop serve
Restart=on-failure
[Install]
WantedBy=default.target
Save it as ~/.config/systemd/user/opendrop.service and run systemctl --user enable --now opendrop. Run loginctl enable-linger $USER once so the service starts at boot without anyone logging in. Check on it any time with opendrop status. The service's output, including the pairing password and QR code, goes to the journal (journalctl --user -u opendrop), so treat that log as private. When you need to pair a phone, opendrop connect-info shows the URL, password and QR code again.
Sending Files from the Command Line
Without a target, opendrop upload copies files into this computer's own OpenDrop storage, where your paired phone can browse and download them. That needs OpenDrop running on the same computer, either the app or opendrop serve. If nothing is running, the command exits with code 2.
With Pro, add -d to send straight to another device on your account:
opendrop upload /path/to/backup.tar.gz -d "My Windows PC"
You can pass several files or a whole folder. Folders arrive with their directory tree intact. Add -s Reports to put the files in a subfolder on the receiving side.
For each file the command prints the name and size, then Uploaded: when it lands. It blocks until every file is done and then exits, so the next line of your script only runs after the transfer has finished. Remote sends retry a few times on their own before they give up.
When the target is on the same network, the CLI sends to its LAN address. Otherwise the transfer goes through the relay. Either way, file contents are encrypted with ChaCha20-Poly1305 before they leave the box, and OpenDrop refuses to fall back to plaintext. The relay can still see file names, sizes and device names, which it needs to route the transfer, so don't put secrets in file names.
The Device Registry and Device Names
With -d, the CLI asks your OpenDrop account which of your devices are online right now, then picks the one you named. opendrop devices prints that list by name. Add -v to also see each device's ID and, for devices that reported one, the LAN address. A phone reachable only through the relay has no LAN line:
Online devices (2):
----------------------------------------
My Windows PC
ID: <device ID>
LAN: 192.168.1.50:8000
My iPhone
ID: <device ID>
Both opendrop devices and -d need the headless box signed in to the same Pro account as your other devices. Run opendrop sign-in and pick Google, Microsoft, Apple, or email and password. The first three use a browser sign-in, so email is the simplest choice on a machine with no desktop. Until the box is signed in to a Pro account, both stop with an error that tells you to sign in, or that the command needs Pro.
How -d matches what you type:
- An exact device name or device ID, ignoring case.
- Part of a name, at least 3 characters long, as long as it matches only one device.
-d windowsworks if only one device has "windows" in its name. - The first 8 or more characters of a device ID.
If what you typed matches nothing, or matches more than one device, the CLI sends nothing. It lists the devices it could have meant (or every online device, when nothing matches) and exits with an error. That is on purpose: a script should never guess which machine gets your files.
Before you schedule anything, run opendrop devices -v by hand on the box. It confirms the box is signed in, shows whether the target is online, and gives you the exact name to put after -d. Device names can be changed in the app; the device ID is the steadier choice for a script that will run for months.
Wiring It Into a Cron Job
Say you want last night's logs on your desktop every morning. The crontab line:
0 2 * * * /usr/local/bin/opendrop upload /var/log/daily-report.tar.gz -d "My Windows PC" >> "$HOME/opendrop-sync.log" 2>&1
Cron runs with a much smaller environment than your shell, and that causes most of the surprises:
- Use full paths. Cron's PATH usually leaves out
/usr/local/bin, so call/usr/local/bin/opendrop, or whereverwhich opendroppoints. - Same user, same config. The CLI keeps its sign-in and settings in
~/.config/opendrop/, or in$XDG_CONFIG_HOME/opendropwhen that variable is set. Cron does not read.bashrcor.profile. If you setXDG_CONFIG_HOMEthere, set it in the crontab too, or the job looks in the default folder, finds no sign-in and fails. Put the job in the crontab of the user who ranopendrop sign-in. - Always pass
-d. Without it,uploadstores the file on this box instead of sending it anywhere, and reports success. - Keep the log. Send stdout and stderr to a file. The CLI prints a specific message for a missing file, a device it cannot match, no devices online, and network failures, so the log usually tells you what went wrong.
The exit code tells a script what happened:
0: every file went through.1: bad arguments or a missing file, or some files failed while others went through.2: the CLI could not find its target (no running server, not signed in, or no matching device online).3: a network error, or every file failed.4: this copy of OpenDrop needs an update.
The target also has to be awake when the job fires. If your desktop sleeps at 2 AM, the upload fails. Schedule the job for a time the target is usually on, or wrap it in a script that retries:
#!/bin/bash
LOG="$HOME/opendrop-sync.log"
FILE=/var/log/daily-report.tar.gz
TARGET="My Windows PC"
echo "$(date): starting transfer" >> "$LOG"
for i in 1 2 3; do
if /usr/local/bin/opendrop upload "$FILE" -d "$TARGET" >> "$LOG" 2>&1; then
exit 0
fi
echo "$(date): attempt $i failed" >> "$LOG"
sleep 60
done
echo "$(date): giving up" >> "$LOG"
exit 1
Point the crontab at the script instead of the raw command.
Where the CLI Falls Short
There is no one-shot receive command. opendrop serve runs until you stop it and saves incoming files to its storage folder. If a script needs to react when a file arrives, watch that folder yourself, for example with inotifywait. On Linux the default folder is ~/Downloads/OpenDrop/Files, or ~/.local/share/opendrop/Files on systems with no Downloads folder. If you moved it, opendrop config storage-directory prints where it is.
Uploads show no progress bar. A large send prints its name and size, then nothing until it finishes or fails. opendrop download does show a progress bar.
Commands that reach another device need OpenDrop Pro, with both devices signed in to the same account. On Free, the CLI still manages this computer's own storage (upload, list, rename, move, delete) and runs the headless server your paired phone connects to.
There is no macOS build yet. The CLI comes with the Windows and Linux apps, and macOS is still in development.
For a box that pushes files on a schedule, that is enough: serve under systemd, upload -d in a short script, and cron to run it. OpenDrop handles discovery, routing and encryption, so the scripts stay short.
Automate Your File Transfers with OpenDrop CLI
The OpenDrop CLI comes with the Windows and Linux apps. Run a headless server and script uploads for free, and send to your other devices with Pro.
Download OpenDrop Free