spill / docs

Command line

spill serve [--config PATH]
spill [--socket PATH] [--json] COMMAND
spill --version

spill serve runs the daemon in the foreground. All other commands talk to a running daemon over its Unix socket. Without --socket, client commands use:

  • Linux: $XDG_RUNTIME_DIR/spill.sock, falling back to ~/.local/state/spill/spill.sock.
  • macOS: ~/Library/Application Support/spill/spill.sock.

Pass --socket if your config sets a different control_socket.

--json prints the daemon’s raw JSON response data instead of text, one document per line. Use it for scripts. --socket and --json can appear before or after the client command.

IDs

A torrent’s ID is its info hash as 40 hex characters. Commands accept any prefix that matches exactly one torrent; an ambiguous prefix is an input error.

Commands

CommandWhat it does
add SOURCE [--output DIR]Add a .torrent file (path) or a magnet: link. --output must be an absolute directory; it is created if missing. Defaults to download_dir. Prints the new ID. Adding a torrent that already exists is an error.
list [--watch]All torrents: ID prefix, state, verified/total bytes, name. --watch refreshes every second until Ctrl-C.
statusSame data as list, plus daemon health. Most useful with --json.
get IDEverything about one torrent: settings, state, progress, uploaded bytes, seeding time, errors, tracker messages, and live transfer details (rates, peers, trackers).
set ID KEY=JSON ...Change per-torrent settings. Values are JSON: numbers, true/false, or arrays. See below.
files IDFiles in torrent order: index, length, priority, path. Requires metadata.
pause IDStop the torrent and keep it paused across restarts.
resume IDAllow a paused torrent to run again (it may wait for a free slot).
recheck IDVerify every piece against the data on disk, then leave the torrent paused. Use after moving or editing files, or after an unclean power loss.
reannounce IDAnnounce to the tracker again as soon as the tracker’s min interval allows. Fails if trackers are disabled for the torrent.
remove ID [--delete-payload]Remove the torrent. Files are kept unless --delete-payload is given; see Torrents.
healthDaemon process ID, number of running torrents and listen address.
shutdownStop the daemon cleanly.

In get JSON, transfer.peers[].transport is "tcp", "utp" or "http" (for web seeds). A uTP peer also has utp_retransmits, the number of resent outgoing uTP datagrams. transfer.utp_retransmits totals these over the current running owner, including peers that have closed; restarting the owner resets it. Counts are sampled while peer I/O is attached; later FIN-linger retransmissions are not included. transfer.pending_contacts counts queued and currently dialing discovery contacts, not established peers. These diagnostics are not wire traces.

Changing settings with set

Keys are the [defaults] keys:

spill set ID download_limit=1048576 upload_limit=524288
spill set ID seed_ratio=2 seed_time=86400
spill set ID trackers=true dht=false pex=false web_seeds=true
spill set ID 'file_priorities=["high","skip","normal"]'
spill set ID 'file_priorities=[]'      # back to all files
  • Quote values that contain brackets or spaces so your shell passes them intact.
  • A running torrent is stopped and restarted with the new settings. A paused torrent stays paused.
  • file_priorities needs one entry per file in files order, including padding files, which must be "skip". File selection needs metadata, so wait for a magnet to resolve first.
  • dht and pex cannot be enabled on private torrents. dht cannot be enabled when the daemon listens on an IPv6 address.

Exit codes

CodeMeaning
0Success
1The operation failed
2Invalid input (bad arguments, values, ambiguous ID, invalid torrent)
3No torrent matches the ID
4Cannot reach the daemon (not running, wrong socket, permission denied)
130list --watch interrupted with Ctrl-C

Control protocol

Client commands send one JSON object per line to the socket and read one JSON response line. Other programs can do the same, for example with socat:

# Linux (when XDG_RUNTIME_DIR is set)
socket="$XDG_RUNTIME_DIR/spill.sock"
# macOS
# socket="$HOME/Library/Application Support/spill/spill.sock"
echo '{"op":"get","id":"3f2a"}' | socat - "UNIX-CONNECT:$socket"

Requests use op plus the same fields as the commands (id, values, delete_payload, magnet, output_dir). For add, metainfo is the .torrent file as a standard base64 string (at most 16 MiB decoded); give either metainfo or magnet. Responses are {"code":0,"data":…,"error":null}; code uses the exit codes above. Requests are limited to about 22 MiB.