rTorrent Complete Command Reference

SkillDev tools

rTorrent XML-RPC command reference focused on remote control, multicall patterns, load methods, and the torrent commands used by Electorrent.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the rTorrent Complete Command Reference skill

What this skill tells your AI

The instructions your AI receives, as published by tympanix/electorrent in .agents/skills/rtorrent-api/SKILL.md and read by ahel’s review.

All commands described using Python-style function signatures:

# Global command (no target needed):
call("system.hostname") -> str

# Download-targeted command (first arg is download info hash):
call("d.name", target: str) -> str

# Download command with extra arguments:
call("d.priority.set", target: str, v: int) -> None

Target types (first RPC argument for each prefix):

PrefixTarget typeDescription
d.*target: strDownload info hash (hex string). Required.
p.*(implicit)Peer. Used inside p.multicall; target is implicit.
f.*(implicit)File. Used inside f.multicall; target is implicit.
t.*(implicit)Tracker. Used inside t.multicall; target is implicit.
fi.*(implicit)File list iterator. Internal use.
(none)Global command, pass "" as target or omit.

Return types:

TypeDescription
strString
int64-bit signed integer
boolBoolean (returns int 0/1 in RPC)
list[T]List of elements
dict[K, V]Key-value map
anyReturn type depends on context
NoneCommand returns nothing meaningful

Table of Contents

  • Download Commands (d.*)
  • Peer Commands (p.*)
  • File Commands (f.*)
  • Tracker Commands (t.*)
  • Choke Group Commands (choke_group.*)
  • Network Commands (network.*)
  • Protocol Commands (protocol.*)
  • System Commands (system.*)
  • Pieces / Chunk Commands (pieces.*)
  • Session Commands (session.*)
  • Throttle Commands (throttle.*)
  • View / UI Commands (view.*, ui.*)
  • Event / Scheduling Commands
  • IP Filter Commands (ip_tables.*, ipv4_filter.*)
  • Logging Commands (log.*)
  • Dynamic Method Commands (method.*)
  • Logic / Control Flow
  • Math Commands (math.*)
  • Conversion Commands (convert.*)
  • Elapsed Time Commands
  • Color Commands (color.*)
  • String Enumeration Commands (strings.*)
  • Scheduler Commands (scheduler.*)
  • File Output / Group Insert
  • Lua Commands
  • Dynamic Ratio Groups

Download Commands (d.*)

Identification / Metadata

call("d.hash", target: str) -> str                        # torrent info hash (hex)
call("d.local_id", target: str) -> str                    # local peer ID (hex)
call("d.local_id_html", target: str) -> str               # local peer ID (HTML escaped)
call("d.bitfield", target: str) -> str                    # completed pieces bitfield (hex)
call("d.base_path", target: str) -> str                   # base filesystem path
call("d.base_filename", target: str) -> str               # base filename
call("d.name", target: str) -> str                        # torrent name
call("d.creation_date", target: str) -> int               # torrent creation date (unix timestamp)
call("d.load_date", target: str) -> int                   # date loaded into client (unix timestamp)

Transfer Stats

call("d.up.rate", target: str) -> int                     # upload rate (bytes/s)
call("d.up.total", target: str) -> int                    # total uploaded (bytes)
call("d.down.rate", target: str) -> int                   # download rate (bytes/s)
call("d.down.total", target: str) -> int                  # total downloaded (bytes)
call("d.skip.rate", target: str) -> int                   # skipped data rate (bytes/s)
call("d.skip.total", target: str) -> int                  # total skipped data (bytes)

PEX

call("d.peer_exchange", target: str) -> bool              # whether PEX is enabled
call("d.peer_exchange.set", target: str, v: bool) -> None # enable/disable PEX

State / Status

call("d.is_open", target: str) -> bool                    # is download open
call("d.is_active", target: str) -> bool                  # is actively transferring
call("d.is_hash_checked", target: str) -> bool            # has hash been checked
call("d.is_hash_checking", target: str) -> bool           # is hash check in progress
call("d.is_multi_file", target: str) -> bool              # is multi-file torrent
call("d.is_private", target: str) -> bool                 # is private torrent
call("d.is_pex_active", target: str) -> bool              # is PEX active
call("d.is_partially_done", target: str) -> bool          # is partially downloaded
call("d.is_not_partially_done", target: str) -> bool      # is not partially downloaded
call("d.is_meta", target: str) -> bool                    # is magnet/metadata download

Lifecycle Control

call("d.resume", target: str) -> None                     # resume download
call("d.pause", target: str) -> None                      # pause download
call("d.open", target: str) -> None                       # open download (allocate files)
call("d.close", target: str) -> None                      # close download
call("d.close.directly", target: str) -> None             # close immediately (no cleanup)
call("d.erase", target: str) -> None                      # erase/remove download
call("d.check_hash", target: str) -> None                 # trigger hash check
call("d.save_resume", target: str) -> None                # save resume data
call("d.save_full_session", target: str) -> None          # save full session data
call("d.update_priorities", target: str) -> None          # update file priorities

Composite Lifecycle (execute multiple steps)

call("d.start", target: str) -> None                     # start: clear hashing_failed, set view=started
call("d.stop", target: str) -> None                      # stop: set view=stopped
call("d.try_start", target: str) -> None                 # start unless hashing_failed or ignore_commands
call("d.try_stop", target: str) -> None                  # stop unless ignore_commands
call("d.try_close", target: str) -> None                 # close unless ignore_commands
call("d.incomplete", target: str) -> bool                # inverse of d.complete

Custom Fields

call("d.custom", target: str, key: str) -> str                    # get custom value (empty if not found)
call("d.custom_throw", target: str, key: str) -> str              # get custom value (throws if not found)
call("d.custom.set", target: str, key: str, value: str) -> None   # set custom value
call("d.custom.if_z", target: str, key: str, default: str) -> str # get custom value or default if empty
call("d.custom.keys", target: str) -> list[str]                   # list all custom keys
call("d.custom.items", target: str) -> dict[str, str]             # all custom key-value pairs

# Shorthand custom string fields:
call("d.custom1", target: str) -> str
call("d.custom1.set", target: str, v: str) -> None
call("d.custom2", target: str) -> str
call("d.custom2.set", target: str, v: str) -> None
call("d.custom3", target: str) -> str
call("d.custom3.set", target: str, v: str) -> None
call("d.custom4", target: str) -> str
call("d.custom4.set", target: str, v: str) -> None
call("d.custom5", target: str) -> str
call("d.custom5.set", target: str, v: str) -> None

State Variables

# state: 0=stopped, 1=started
call("d.state", target: str) -> int
call("d.state.set", target: str, v: int) -> None

# complete: 0=not complete, 1=complete
call("d.complete", target: str) -> int
call("d.complete.set", target: str, v: int) -> None

# mode: 0=off, 1=scheduled, 2=forced on, 3=forced off
call("d.mode", target: str) -> int
call("d.mode.set", target: str, v: int) -> None

# hashing: 0=not hashing, 1=normal, 2=download finished hashing, 3=rehashing
call("d.hashing", target: str) -> int
call("d.hashing.set", target: str, v: int) -> None

# tied_to_file: file this download is associated with
call("d.tied_to_file", target: str) -> str
call("d.tied_to_file.set", target: str, v: str) -> None

# loaded_file: file this torrent was loaded from (setter is private/not in RPC)
call("d.loaded_file", target: str) -> str

# state_changed: unix timestamp of last state change
call("d.state_changed", target: str) -> int
call("d.state_changed.set", target: str, v: int) -> None

# state_counter: number of state changes
call("d.state_counter", target: str) -> int
call("d.state_counter.set", target: str, v: int) -> None

# ignore_commands: whether to ignore commands
call("d.ignore_commands", target: str) -> int
call("d.ignore_commands.set", target: str, v: int) -> None

# hashing_failed: whether hash check failed
call("d.hashing_failed", target: str) -> bool
call("d.hashing_failed.set", target: str, v: bool) -> None

Timestamps

# .set and .set_if_z are private (not available via RPC)
call("d.timestamp.started", target: str) -> int                  # start timestamp (unix)
call("d.timestamp.started.set", target: str, v: int) -> None     # set start timestamp (PRIVATE)
call("d.timestamp.started.set_if_z", target: str, v: int) -> None # set only if currently zero (PRIVATE)
call("d.timestamp.started.or_zero", target: str) -> int           # get timestamp or 0 if unset
call("d.timestamp.started.elapsed", target: str, v: int) -> bool  # true if (now - timestamp) > v

call("d.timestamp.finished", target: str) -> int                  # finish timestamp (unix)
call("d.timestamp.finished.set", target: str, v: int) -> None     # set finish timestamp (PRIVATE)
call("d.timestamp.finished.set_if_z", target: str, v: int) -> None # set only if currently zero (PRIVATE)
call("d.timestamp.finished.or_zero", target: str) -> int           # get timestamp or 0 if unset
call("d.timestamp.finished.elapsed", target: str, v: int) -> bool  # true if (now - timestamp) > v

Connection / Choke Heuristics

call("d.connection_current", target: str) -> str                         # current connection type
call("d.connection_current.set", target: str, type: str) -> None         # set connection type
call("d.connection_leech", target: str) -> str                           # connection when leeching (setter private)
call("d.connection_seed", target: str) -> str                            # connection when seeding (setter private)

call("d.up.choke_heuristics", target: str) -> str                        # current upload choke heuristics
call("d.up.choke_heuristics.set", target: str, heur: str) -> None        # set upload choke heuristics
call("d.down.choke_heuristics", target: str) -> str                      # current download choke heuristics
call("d.down.choke_heuristics.set", target: str, heur: str) -> None      # set download choke heuristics

call("d.up.choke_heuristics.leech", target: str) -> str                  # upload heuristics when leeching (setter private)
call("d.up.choke_heuristics.seed", target: str) -> str                   # upload heuristics when seeding (setter private)
call("d.down.choke_heuristics.leech", target: str) -> str                # download heuristics when leeching (setter private)
call("d.down.choke_heuristics.seed", target: str) -> str                 # download heuristics when seeding (setter private)

Views

call("d.views", target: str) -> list                                # list of views this download belongs to
call("d.views.has", target: str, view: str) -> int                  # is download in this view (0/1)
call("d.views.push_back", target: str, view: str) -> None           # add to view
call("d.views.push_back_unique", target: str, view: str) -> None    # add to view (no duplicates)
call("d.views.remove", target: str, view: str) -> None              # remove from view

Peer Limits

call("d.peers_min", target: str) -> int                            # min peers
call("d.peers_min.set", target: str, v: int) -> None               # set min peers
call("d.peers_max", target: str) -> int                            # max peers
call("d.peers_max.set", target: str, v: int) -> None               # set max peers
call("d.uploads_max", target: str) -> int                          # max upload slots
call("d.uploads_max.set", target: str, v: int) -> None             # set max upload slots
call("d.uploads_min", target: str) -> int                          # min upload slots
call("d.uploads_min.set", target: str, v: int) -> None             # set min upload slots
call("d.downloads_max", target: str) -> int                        # max download slots
call("d.downloads_max.set", target: str, v: int) -> None           # set max download slots
call("d.downloads_min", target: str) -> int                        # min download slots
call("d.downloads_min.set", target: str, v: int) -> None           # set min download slots

call("d.peers_connected", target: str) -> int                      # number of connected peers
call("d.peers_not_connected", target: str) -> int                  # number of not-connected peers
call("d.peers_complete", target: str) -> int                       # number of seed peers
call("d.peers_accounted", target: str) -> int                      # number of accounted peers
call("d.disconnect.seeders", target: str) -> None                  # disconnect all seeders

Seeder Acceptance / Throttle

call("d.accepting_seeders", target: str) -> bool                   # accepting seeders
call("d.accepting_seeders.enable", target: str) -> None            # enable accepting seeders
call("d.accepting_seeders.disable", target: str) -> None           # disable accepting seeders
call("d.throttle_name", target: str) -> str                        # assigned throttle name
call("d.throttle_name.set", target: str, name: str) -> None        # set throttle name

Progress / Size

call("d.bytes_done", target: str) -> int                           # bytes downloaded
call("d.ratio", target: str) -> int                                # share ratio (upload/download * 1000)
call("d.chunks_hashed", target: str) -> int                        # number of chunks hashed
call("d.free_diskspace", target: str) -> int                       # free disk space (bytes)
call("d.size_files", target: str) -> int                           # number of files
call("d.size_bytes", target: str) -> int                           # total size (bytes)
call("d.size_chunks", target: str) -> int                          # number of chunks
call("d.chunk_size", target: str) -> int                           # chunk size (bytes)
call("d.size_pex", target: str) -> int                             # number of PEX peers
call("d.max_size_pex", target: str) -> int                         # max PEX peers
call("d.chunks_seen", target: str) -> str                          # chunks seen across peers (hex)
call("d.completed_bytes", target: str) -> int                      # bytes completed
call("d.completed_chunks", target: str) -> int                     # chunks completed
call("d.left_bytes", target: str) -> int                           # bytes remaining
call("d.wanted_chunks", target: str) -> int                        # number of wanted chunks

Trackers

call("d.tracker_announce", target: str) -> None                    # trigger tracker announce
call("d.tracker_announce.force", target: str) -> None              # force announce (bypass interval)
call("d.tracker_numwant", target: str) -> int                      # numwant value
call("d.tracker_numwant.set", target: str, v: int) -> None         # set numwant
call("d.tracker_focus", target: str) -> int                        # focused tracker index (deprecated)
call("d.tracker_size", target: str) -> int                         # number of trackers

call("d.tracker.has_active", target: str) -> bool                  # any active tracker
call("d.tracker.has_active_not_scrape", target: str) -> bool       # any active non-scrape tracker
call("d.tracker.has_usable", target: str) -> bool                  # any usable tracker
call("d.tracker.insert", target: str, group: int, url: str) -> None # insert extra tracker
call("d.tracker.send_scrape", target: str, group: int) -> None     # send scrape request

Directory / Priority / Group

call("d.directory", target: str) -> str                            # download directory
call("d.directory.set", target: str, path: str) -> None            # set download directory
call("d.directory_base", target: str) -> str                       # download base directory
call("d.directory_base.set", target: str, path: str) -> None       # set base directory directly

call("d.priority", target: str) -> int                             # priority: 0=off, 1=low, 2=normal, 3=high
call("d.priority.set", target: str, v: int) -> None                # set priority
call("d.priority_str", target: str) -> str                         # priority as string

call("d.group", target: str) -> int                                # choke group index
call("d.group.name", target: str) -> str                           # choke group name
call("d.group.set", target: str, group: int | str) -> None         # set choke group (by index or name)

call("d.message", target: str) -> str                              # download message
call("d.message.set", target: str, msg: str) -> None               # set download message
call("d.max_file_size", target: str) -> int                        # max file size
call("d.max_file_size.set", target: str, v: int) -> None           # set max file size

Symlinks / Tied Files

# type: "base_path", "base_filename", or "tied"
call("d.create_link", target: str, type: str, prefix: str, postfix: str) -> None  # create symlink
call("d.delete_link", target: str, type: str, prefix: str, postfix: str) -> None  # delete symlink
call("d.delete_tied", target: str) -> None                                        # delete tied file

Multicall / Peer Targeting

# Iterate over files of a download. filter: regex pattern or "" for all files.
call("f.multicall", target: str, filter: str, *cmds: str) -> list[list[any]]

# Iterate over peers of a download.
call("p.multicall", target: str, *cmds: str) -> list[list[any]]

# Iterate over trackers of a download.
call("t.multicall", target: str, *cmds: str) -> list[list[any]]

# Call a command on a specific peer identified by download hash and peer ID (hex).
call("p.call_target", dl_hash: str, peer_id: str, cmd: str, *args: any) -> any

# Add a peer to a download.
call("add_peer", target: str, hostport: str) -> None

Peer Commands (p.*)

Used inside p.multicall. No explicit target argument — the target (peer) is implicit.

call("p.id") -> str                          # peer ID (hex)
call("p.id_html") -> str                     # peer ID (HTML escaped)
call("p.client_version") -> str              # client version string
call("p.options_str") -> str                 # options bitmask (hex)

call("p.is_encrypted") -> bool               # connection encrypted
call("p.is_incoming") -> bool                # incoming connection
call("p.is_obfuscated") -> bool              # connection obfuscated
call("p.is_snubbed") -> bool                 # peer is snubbed
call("p.is_unwanted") -> bool                # peer is unwanted
call("p.is_preferred") -> bool               # peer is preferred

call("p.address") -> str                     # IP address (IPv6 in brackets)
call("p.port") -> int                        # port number
call("p.completed_percent") -> int           # completion percentage

call("p.up_rate") -> int                     # upload rate to peer (bytes/s)
call("p.up_total") -> int                    # total uploaded to peer (bytes)
call("p.down_rate") -> int                   # download rate from peer (bytes/s)
call("p.down_total") -> int                  # total downloaded from peer (bytes)
call("p.peer_rate") -> int                   # peer's reported rate (bytes/s)
call("p.peer_total") -> int                  # peer's reported total (bytes)

call("p.snubbed") -> bool                    # is snubbed
call("p.snubbed.set", v: bool) -> None       # set snubbed state
call("p.banned") -> bool                     # is banned
call("p.banned.set", v: bool) -> None        # set banned state

call("p.disconnect") -> None                 # disconnect peer
call("p.disconnect_delayed") -> None         # disconnect peer (delayed)

File Commands (f.*)

Used inside f.multicall. No explicit target argument — the target (file) is implicit.

call("f.is_created") -> bool                 # file exists on disk
call("f.is_open") -> bool                    # file is open

call("f.is_create_queued") -> bool           # creation is queued
call("f.is_resize_queued") -> bool           # resize is queued
call("f.set_create_queued") -> None          # mark for creation
call("f.set_resize_queued") -> None          # mark for resize
call("f.unset_create_queued") -> None        # unmark creation
call("f.unset_resize_queued") -> None        # unmark resize

call("f.prioritize_first") -> bool           # prioritize-first flag
call("f.prioritize_first.enable") -> None    # enable prioritize-first
call("f.prioritize_first.disable") -> None   # disable prioritize-first
call("f.prioritize_last") -> bool            # prioritize-last flag
call("f.prioritize_last.enable") -> None     # enable prioritize-last
call("f.prioritize_last.disable") -> None    # disable prioritize-last

call("f.size_bytes") -> int                  # file size (bytes)
call("f.size_chunks") -> int                 # number of chunks
call("f.completed_chunks") -> int            # completed chunks
call("f.offset") -> int                      # byte offset in torrent
call("f.range_first") -> int                 # first chunk index
call("f.range_second") -> int                # last chunk index + 1

call("f.priority") -> int                    # file priority
call("f.priority.set", v: int) -> None       # set file priority
call("f.path") -> str                        # full file path
call("f.path_components") -> list[str]       # path split into components
call("f.path_depth") -> int                  # number of path components
call("f.frozen_path") -> str                 # frozen path string
call("f.match_depth_prev") -> int            # match depth with previous file
call("f.match_depth_next") -> int            # match depth with next file
call("f.last_touched") -> int                # last touched timestamp

File Iterator (fi.*)

Internal use for file list iteration.

call("fi.filename_last") -> str              # filename at current depth level
call("fi.is_file") -> bool                   # is a file (not directory)

Tracker Commands (t.*)

Used inside t.multicall. No explicit target argument — the target (tracker) is implicit.

call("t.is_busy") -> bool                    # tracker is busy
call("t.is_enabled") -> bool                 # tracker is enabled
call("t.is_extra_tracker") -> bool           # is an extra (user-added) tracker
call("t.is_open") -> bool                    # tracker is open/busy
call("t.is_scrapable") -> bool               # supports scrape
call("t.is_usable") -> bool                  # is usable
call("t.can_scrape") -> bool                 # deprecated: same as t.is_scrapable

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
1k
Forks
98
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
rtorrent-api
Source
github.com/tympanix/electorrent