Files, where they belong. A fast, native Rust file drop for computers, devices, and programs.
Bitsend has a host GUI, a client GUI, a CLI, and two threaded HTTP servers on the same host IP.
| Server | Default port | Used by | Authentication | Purpose |
|---|---|---|---|---|
| Host/control server | 8787 |
Host GUI, bitsend-cli, admin automation |
Static host token | Program/device records, API-key generation, kick/restore/regenerate, host status/config |
| Client/data server | 8788 |
Bitsend Client and programs | Per-device 16-character API key | Status, heartbeat, file listing, streaming upload/download |
Both servers bind to 0.0.0.0 and therefore work over Ethernet, Wi-Fi, and Tailscale. They use separate Tokio multi-threaded runtimes. The data server never accepts the host token, and the control server never accepts a device API key.
For a remote program, use:
http://HOST_TAILSCALE_IP:8788 + X-Bitsend-Api-Key: YOUR_16_CHARACTER_KEY
A program needs both the host's Tailscale IP and its own API key to use the client/data server. See md/agent.md for the full program-integration contract and request examples.
- Native cross-platform GUI built with
egui/eframe. - Google Material Symbols Rounded icons bundled for the native GUI and landing page.
- Pastel flat UI with lightweight status animations and no gradients.
- Async Rust HTTP APIs built with Axum and Tokio.
- Separate threaded control and data servers for responsive administration during transfers.
- Streaming uploads and downloads; uploads are limited to 10 GiB by default.
- Configurable host drop folder.
- Host GUI shows local IP, Tailscale IP, both ports, static host token, JSON path, and devices/programs.
- Generate a persistent 16-character API key for every program or device.
- Kick without deleting; restore later or regenerate a replacement key.
- Device/program records and authorization state survive restarts in JSON.
- Client GUI requires an API key before displaying host information or files.
- CLI for pairing programs, generating keys, checking status, listing, uploading, downloading, and administration.
- No database or external service is required.
The website/ directory is a dependency-free GitHub Pages landing page with the same pastel, flat visual system as the native GUI. It includes responsive animation, no gradients, and a bundled Google Material Symbols font with no JavaScript library dependency. Use website/assets/bitsend-cover.svg as the repository's 1280x640 social-preview artwork. The included .github/workflows/pages.yml publishes the site from GitHub Actions; replace YOUR_GITHUB_USERNAME in the website links before publishing.
- Linux Mint build, .deb packaging, Tailscale, and troubleshooting
- Windows build, .exe packaging, Tailscale, and troubleshooting
- Program and API integration guide
- Contributing
- Security policy
- Website and GitHub Pages guide
The packaging scripts are packaging/build-deb.sh and packaging/build-windows.ps1. The Linux package contains the host, client, and CLI binaries. A Linux host and Windows client are protocol-compatible. For a CLI-only build without the native GUI stack, use cargo build --release --locked --no-default-features --bin bitsend-cli. A verified Linux Mint package and matching Linux binaries are in artifacts/linux/; Windows .exe packages are produced by the GitHub Actions release workflow.
Install a current stable Rust toolchain using rustup. Rust 1.80 or newer is recommended.
On Debian/Ubuntu:
sudo apt update
sudo apt install build-essential pkg-config libx11-dev libxcb1-dev \
libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \
libxkbcommon-dev libwayland-devLinux needs a working X11 or Wayland desktop session.
Install the MSVC Rust toolchain and Visual Studio Build Tools with the Desktop C++ workload. Windows Defender Firewall may ask whether bitsend-host.exe should accept private-network connections; allow it for networks where the host should be reachable.
cd bitsend
cargo fmt
cargo test --lib --locked -j 1
cargo build --release --locked -j 1Release binaries are written to target/release/:
bitsend-host/bitsend-host.exebitsend-client/bitsend-client.exebitsend-cli/bitsend-cli.exe
Start the host computer:
cargo run --release --bin bitsend-hostStart a GUI client:
cargo run --release --bin bitsend-clientThe host remains running while its GUI process is running. It starts both API servers in the background.
bitsend-host --port 8787 --client-port 8788 --data-file /path/to/bitsend-host.jsonAliases: --admin-port is the same as --port.
On Windows PowerShell:
bitsend-host.exe --port 8787 --client-port 8788 `
--data-file "$env:APPDATA\Bitsend\host.json"If no options are supplied, the host uses ports 8787 and 8788.
The default host JSON path is:
- Linux:
$XDG_CONFIG_HOME/bitsend/host.json, or$HOME/.config/bitsend/host.json - Windows:
%APPDATA%\Bitsend\host.json
The default drop folder is BitsendDrop in the directory from which the host was first launched. Change it from the host GUI.
With UFW on Linux, allow both private-network ports if needed:
sudo ufw allow 8787/tcp
sudo ufw allow 8788/tcp- Start Bitsend Host.
- Confirm the Tailscale client/data address shown in the connection details.
- Enter a program name and type, such as
backup-agentandprogram. - Click Add + generate API key.
- Give the program the displayed 16-character API key.
- Configure the program with the host Tailscale IP and client/data port
8788.
The static host token is visible in the host GUI. Use it only against the host/control port:
bitsend-cli keygen \
--admin http://HOST_TAILSCALE_IP:8787 \
--host-token STATIC_HOST_TOKEN \
--name backup-agent \
--kind programThe command prints the persistent API key. The alias pair performs the same operation.
For automation, use --json:
bitsend-cli keygen --admin http://HOST_TAILSCALE_IP:8787 \
--host-token STATIC_HOST_TOKEN --name backup-agent \
--kind program --jsonA kicked device can be paired again with its existing --device-id; this creates a fresh key and reauthorizes that record.
Use the client/data port and API key for every program data operation:
# Check that the authenticated data server is working
bitsend-cli status \
--server http://HOST_TAILSCALE_IP:8788 \
--api-key PROGRAM_API_KEY
# Keep the program marked online
bitsend-cli heartbeat \
--server http://HOST_TAILSCALE_IP:8788 \
--api-key PROGRAM_API_KEY
# List the drop folder
bitsend-cli list \
--server http://HOST_TAILSCALE_IP:8788 \
--api-key PROGRAM_API_KEY
# Send a file
bitsend-cli upload \
--server http://HOST_TAILSCALE_IP:8788 \
--api-key PROGRAM_API_KEY \
--file ./state.db
# Download a file
bitsend-cli download \
--server http://HOST_TAILSCALE_IP:8788 \
--api-key PROGRAM_API_KEY \
--name state.db \
--output ./state-copy.dbUse bitsend-cli help for all commands. admin-status, list, status, upload, and the other administration commands support --json where useful.
Install and sign in to Tailscale on both computers and ensure they are in the same tailnet. In the host GUI, use the displayed Tailscale client API address, for example:
http://100.64.12.34:8788
If the host GUI says Tailscale was not detected, start the Tailscale service and wait for its network scan or reopen Bitsend Host.
All control endpoints require either:
X-Bitsend-Host-Token: STATIC_HOST_TOKEN
or:
Authorization: Bearer STATIC_HOST_TOKEN
Endpoints:
| Method | Path | Purpose |
|---|---|---|
GET |
/api/v1/admin/status |
Control status, both ports, detected IPs, and remembered devices |
GET |
/api/v1/admin/config |
Current host/control and client/data configuration |
GET |
/api/v1/admin/devices |
List programs/devices and their keys |
POST |
/api/v1/admin/devices |
Create a program/device key |
POST |
/api/v1/admin/api-keys |
Alias for key generation |
POST |
/api/v1/admin/devices/{id}/kick |
Disable a device without deleting it |
POST |
/api/v1/admin/devices/{id}/restore |
Reauthorize a kicked device with its existing key |
POST |
/api/v1/admin/devices/{id}/regenerate |
Replace its key and authorize it |
POST |
/api/v1/pair |
JSON host-token pairing alias |
Create a key directly:
curl -sS -X POST http://HOST_TAILSCALE_IP:8787/api/v1/admin/api-keys \
-H 'X-Bitsend-Host-Token: STATIC_HOST_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"backup-agent","kind":"program"}'All data endpoints require:
X-Bitsend-Api-Key: 16_CHARACTER_PROGRAM_KEY
or Authorization: Bearer 16_CHARACTER_PROGRAM_KEY.
| Method | Path | Purpose |
|---|---|---|
GET |
/api/v1/info |
Authenticated server/device information and file list |
GET |
/api/v1/status |
Authenticated working/status response |
POST |
/api/v1/heartbeat |
Mark a program online |
GET |
/api/v1/files |
List files |
POST |
/api/v1/files |
Multipart upload with field name file |
GET |
/api/v1/files/{filename} |
Stream a file from the drop folder |
Example upload:
curl -X POST http://HOST_TAILSCALE_IP:8788/api/v1/files \
-H 'X-Bitsend-Api-Key: PROGRAM_API_KEY' \
-F 'file=@./state.db'- Bitsend is intended for a trusted LAN or a Tailscale network, not direct public-Internet exposure.
- Plain HTTP sends credentials over the local network without TLS. Tailscale encrypts tailnet traffic. Use an HTTPS reverse proxy if TLS is required outside Tailscale.
- The static host token can create keys and administer all devices. Protect it like an administrator password.
- Per-program API keys grant access to the client/data server and should be kept secret.
- The host JSON contains the host token and API keys. Protect it with operating-system file permissions.
- The API rejects path traversal and refuses symlink entries when downloading.
- Kicking blocks a key immediately. Regenerate if a key may have been copied.
cargo fmt
cargo test --lib --locked -j 1
cargo clippy --all-targets --all-features
cargo build --release --locked -j 1