npm install @ctrl/rqbit
Requires Node.js 24 or newer.
import { Rqbit } from '@ctrl/rqbit';
const client = new Rqbit({
baseUrl: 'http://localhost:3030/',
// only needed when rqbit is started with RQBIT_HTTP_BASIC_AUTH_USERPASS
username: 'admin',
password: 'adminadmin',
});
async function main() {
const res = await client.getAllData();
console.log(res);
}
Docs: https://rqbit.ep.workers.dev
rqbit has no published api reference, GET / on the server lists every endpoint (client.getApiInfo()). The types here are based on responses from rqbit 9.0.1 and its http api source.
Things that work differently from the other clients:
addTimeout (default 60 seconds) instead of timeout.label is ignored, queueUp/queueDown throw, and dateAdded is an empty string.createTorrent needs rqbit started with RQBIT_HTTP_API_ALLOW_CREATE=true, and getStreamUrl/getPlaylistUrl urls need the same basic auth as the api.overwrite: true by default, like Radarr does. rqbit refuses to add a torrent whose files already exist on disk otherwise.RqbitApiError with the http status and rqbit's error kind, ex - torrent_not_found. Timeouts and network errors are also RqbitApiError with no status.total_bytes only counts the pieces of selected files. getTorrent uses the file list for totalSize, getAllData skips the extra request per torrent so its totalSize is the selected size.These functions are normalized through @ctrl/shared-torrent, which makes it easier to support multiple torrent clients. See below for alternative supported torrent clients.
Returns all torrent data and an array of label objects. Data has been normalized and does not match the output of native listTorrents(). rqbit has no labels so labels is always empty.
const data = await client.getAllData();
console.log(data.torrents);
Returns one torrent data from torrent hash
const data = await client.getTorrent('torrent-hash');
console.log(data);
Pause or resume one or more torrents
await client.pauseTorrent('torrent-hash');
await client.resumeTorrent(['torrent-hash', 'other-torrent-hash']);
Remove one or more torrents, throws if a torrent doesn't exist. Does not remove data on disk by default.
// does not remove data on disk
await client.removeTorrent('torrent-hash', false);
// remove data on disk
await client.removeTorrent(['torrent-hash', 'other-torrent-hash'], true);
Add a torrent from a magnet link or torrent file, has client specific options. Also see normalizedAddTorrent
import { readFileSync } from 'node:fs';
const result = await client.addTorrent(new Uint8Array(readFileSync('./linux.torrent')), {
output_folder: '/downloads/linux',
});
console.log(result.details.info_hash);
Add a torrent and return normalized torrent data. rqbit cannot add a torrent paused, startPaused pauses it right after adding.
const result = await client.normalizedAddTorrent('magnet:?xt=urn:btih:...', {
startPaused: true,
});
console.log(result);
Failed requests throw a TorrentClientError from @ctrl/shared-torrent with a code of torrent_not_found, unauthorized, request_failed or client_error, the http status when there is one and the original error as the cause. rqbit errors are a RqbitApiError, a TorrentClientError that also has rqbit's error kind.
import { TorrentClientError } from '@ctrl/rqbit';
try {
await client.getTorrent('torrent-hash');
} catch (error) {
if (error instanceof TorrentClientError && error.code === 'torrent_not_found') {
// not in the client
}
}
rqbit uses basic auth on every request so there is no session to save, this exists to match the other clients.
const state = client.exportState();
const restored = Rqbit.createFromState(config, state);
All of the following npm modules provide the same normalized functions along with supporting the unique apis for each client.
Usenet clients with the same normalized approach:
docker run -d \
--name=rqbit \
-e RQBIT_HTTP_BASIC_AUTH_USERPASS=admin:adminadmin \
-e RQBIT_HTTP_API_ALLOW_CREATE=true \
-p 3030:3030 \
-p 4240:4240 \
-v ~/Documents/rqbit/downloads:/home/rqbit/downloads \
--restart unless-stopped \
ikatson/rqbit:latest