Configuration
A field-by-field reference for every Shelfarr setting — its type, default and what it does.
Use it while configuring integrations, paths, queue behaviour, result selection, notifications and authentication.
⚙️
Most settings live in Admin → Settings. Download clients are managed under
Admin → Download Clients, and per-indexer routing under
Admin → Download Routing. Per-user API tokens are created from
Profile → API tokens.
🧩
You don't need everything. A minimal setup is one indexer (or a direct source), one download
client, and your output paths. Everything else is optional and has a sensible default.
Indexers #
Shelfarr searches indexers through Prowlarr, Jackett or Newznab/NZBHydra2. Pick one provider with indexer_provider.
Searches broaden automatically: Shelfarr starts with a structured book search, then tries progressively looser name-based queries — exact title, title + author, subtitle-stripped title, author-first ordering, and roman/arabic series-number variants (III ↔ 3) — until a strong match is found. Results found by broader queries carry a small confidence penalty and record the query that found them in their score breakdown. With the default broad scope a category-less pass runs as well: releases that look like video content (resolution tags, S01E05 markers, video codecs) are rejected, and when nothing clears min_match_confidence the best few low-confidence candidates are kept for manual review instead of returning an empty search.
| Setting | Type | Default | Description |
indexer_provider | string | (empty) | Active provider: prowlarr, jackett, newznab or none. Leave unset on upgrades to keep legacy Prowlarr config. |
indexer_search_scope | string | broad | Category strategy: broad (book categories plus a filtered category-less pass), strict (book categories only), unrestricted (no category filters, quality filtering only) or custom (only the category IDs configured in the admin UI). |
prowlarr_url | string | (empty) | Base URL for Prowlarr (e.g. http://localhost:9696). |
prowlarr_api_key | string | (empty) | API key from Prowlarr → Settings → General. |
prowlarr_tags | string | (empty) | Comma-separated tag IDs or names to filter indexers (empty = all). |
jackett_url | string | (empty) | Base URL for Jackett (e.g. http://localhost:9117). |
jackett_api_key | string | (empty) | API key from the Jackett dashboard. |
jackett_indexer_filter | string | all | Torznab indexer filter. Use all or a Jackett filter such as tag:books. |
newznab_url | string | (empty) | Base URL or /api endpoint for NZBHydra2 or another Newznab-compatible provider (e.g. http://localhost:5076). |
newznab_api_key | string | (empty) | API key from NZBHydra2 or your Newznab provider. |
Download Clients #
Each client is created in Admin → Download Clients. Supported adapters: qbittorrent, decypharr, deluge, transmission (torrent) and sabnzbd, nzbget (usenet).
| Field | Required | Description |
name | Required | Display name shown in Shelfarr (e.g. Home qBittorrent). |
client_type | Required | Which adapter to use, from the list above. |
url | Required | Base URL including protocol and port. |
username | Optional | Required by clients that use user/password authentication. |
password | Optional | Password for authenticated clients. Stored encrypted. |
api_key | Optional | API key used by SABnzbd. Stored encrypted. |
category | Optional | Category/tag applied in the download client, for routing and filtering. |
download_path | Optional | Client-specific completed download path override. |
enabled | Required | When disabled, Shelfarr won't use the client for new downloads. |
priority | Required | Order within the same type. Lower values are preferred first. |
torrent_verification_max_attempts | Optional | Torrent clients only. Times Shelfarr re-checks a torrent was accepted (default 10). |
torrent_verification_wait_time | Optional | Torrent clients only. Seconds between verification attempts (default 2). |
🧭
Use Admin → Download Routing to send specific indexers to specific clients per download type.
Audiobookshelf #
Optional. When configured, Shelfarr triggers library scans after a download lands and enriches metadata.
| Setting | Type | Default | Description |
audiobookshelf_url | string | (empty) | Base URL for Audiobookshelf (e.g. http://localhost:13378). |
audiobookshelf_api_key | string | (empty) | API token from Audiobookshelf user settings. |
audiobookshelf_audiobook_library_id | string | (empty) | Library ID for audiobooks. |
audiobookshelf_ebook_library_id | string | (empty) | Library ID for ebooks. |
audiobookshelf_library_sync_interval | integer | 3600 | Seconds between automatic library sync jobs. |
Open Library is always available. Hardcover is optional and used first when metadata_source is auto.
| Setting | Type | Default | Description |
metadata_source | string | auto | Primary source: auto (Hardcover first, Open Library fallback), hardcover or openlibrary. |
hardcover_api_token | string | (empty) | API token from hardcover.app/account/api. |
hardcover_search_limit | integer | 10 | Max search results from Hardcover. |
open_library_search_limit | integer | 20 | Max search results from Open Library. |
Direct Downloads #
Optional sources that download directly, without an indexer or download client. Anna's Archive covers ebooks and audiobooks, Z-Library covers ebooks, and LibriVox provides free public-domain audiobooks.
| Setting | Type | Default | Description |
anna_archive_enabled | boolean | false | Enable Anna's Archive as an additional ebook and audiobook search source. |
anna_archive_url | string | https://annas-archive.gl | HTTPS base URLs to try. Shelfarr uses the first compatible public URL. |
anna_archive_api_key | string | (empty) | Member API key (requires a donation). |
flaresolverr_url | string | (empty) | FlareSolverr endpoint for bypassing DDoS protection (e.g. http://flaresolverr:8191). Isolate it from private, link-local, and cloud metadata networks. |
zlibrary_enabled | boolean | false | Enable Z-Library as an additional ebook source. This unofficial integration may break if the service changes. |
zlibrary_url | string | (built-in list) | Base URLs to try. Shelfarr uses the first that accepts your login. |
zlibrary_email | string | (empty) | Z-Library account email used for login. |
zlibrary_password | string | (empty) | Z-Library account password. Stored encrypted. |
librivox_enabled | boolean | false | Enable LibriVox as a free public-domain audiobook source. |
librivox_url | string | https://librivox.org | LibriVox base URL. |
librivox_search_limit | integer | 20 | Maximum number of LibriVox audiobook results to return. |
Third-Party Stores BETA #
Optional catalog offers shown separately from downloadable acquisition results. The first provider is eBooks.com and is limited to editions the API explicitly reports as DRM-free.
| Setting | Type | Default | Description |
ebooks_com_enabled | boolean | false | Show beta DRM-free eBooks.com offers. Checkout and payment remain on eBooks.com. Confirm affiliate or partner permission before production use. |
ebooks_com_country_code | string | (empty) | ISO 3166-1 two-letter buyer country used for territorial availability, currency, and localized prices, for example US, GB, or PT. |
ebooks_com_search_limit | integer | 5 | Maximum matching offers retained per ebook request; clamped to 1–10. |
⚠️
Store offers are never auto-selected or sent to a download client. Shelfarr does not handle store accounts, payment, orders, or automatic bookshelf download. See the
Third-party stores beta guide.
Audible Backup, powered by Libation BETA #
Managed from Admin → Audible Backup in Settings-style Overview, Connection, Automation, and diagnostic Catalog tabs. This optional owned-library backup uses the separately packaged, pinned Libation companion and never asks Shelfarr for an Audible password.
| Admin field | Default | Description |
Companion URL | http://shelfarr-libation:8080 | Internal base URL. The standard Compose value comes from SHELFARR_LIBATION_URL. Public endpoints must use HTTPS; HTTP is accepted only for resolved private/loopback addresses. |
Bridge token | (token file) | Leave blank while the URL matches SHELFARR_LIBATION_URL. A different URL requires its own token, stored in a dedicated encrypted attribute; the bundled token is never sent to that host. |
Enable Audible Backup beta | false | Opt in to account, sync, Library, individual-title, and confirmed existing-library backup actions. |
Allow local/private companion address | true | Required for the standard private Compose hostname. Disable it only when the companion is reached through an appropriately secured public address. |
Request timeout | 30 | HTTP request timeout in seconds, from 1–120. Long-running sync and backup work is polled asynchronously. |
Sync the Audible library automatically | false | Opt in to scheduled owned-library refreshes. Manual sync remains available. Turning this off also turns off automatic backup. |
Sync interval | Every 24 hours | Choose every hour, 6 hours, 12 hours, 24 hours, 3 days, or weekly. The interval is inactive until scheduled sync is enabled; adding the hourly option does not change the 24-hour default. |
Back up existing library | Confirmation required | After the first sync, Overview asks whether to queue eligible existing purchased audiobooks. The same reusable action is available in Automation. Each run recalculates the count, excludes subscriptions, local matches, identity conflicts, and prior backup/import attempts, then records a durable bounded background batch. Libation processes one admitted title at a time and progress is managed from Library. |
Automatically back up new purchases | false | Separate opt-in available after the first successful sync and requiring scheduled sync. The next manual or scheduled sync refreshes a no-download baseline; purchased audiobooks first discovered by later successful syncs are queued and attributed to the administrator who enabled it. It never starts the existing-library batch. |
Use Connection to save and test the companion and manage Audible sign-in, Overview for readiness and the first existing-library decision, Automation for scheduling and explicit backup actions, and the main Library for queue progress and retries. Audible account email and marketplace are sent only when starting Libation's external sign-in; they are not Shelfarr password credentials. The validated sign-in link remains in encrypted, short-lived Shelfarr state across reloads until completion or expiry. During a serialized sync or backup, account status can show Busy while cached titles and job progress remain available.
| Deployment setting | Default | Description |
SHELFARR_LIBATION_URL | http://shelfarr-libation:8080 | Private companion base URL. Do not expose the companion port publicly. |
SHELFARR_LIBATION_TOKEN_FILE | /run/shelfarr-libation/token | Bearer-token file mounted read-only into Shelfarr and used only for the configured SHELFARR_LIBATION_URL. |
SHELFARR_LIBATION_IMPORT_ROOT | /imports/libation | Read-only Shelfarr side of the shared completed-backup volume. The companion sees the same storage at /data. |
LIBATION_BOOKS_PATH | libation_books | Optional host bind path for retained Libation copies. Set it in .env for large libraries instead of using Docker's default named-volume location. |
PUID / PGID | 1000 | The same IDs are passed to Shelfarr and the companion so the mode-0600 bridge token and shared files remain accessible. |
CHOWN_ON_START | auto | Passed to both containers. auto initializes fresh volumes while avoiding unnecessary root ownership changes; use never only for correctly pre-permissioned/root-squashed mounts, or always to fail on an ownership-adjustment error. The Audible companion rejects group/world-accessible private state and credential/token files even in never mode. |
LIBATION_FILES_DIR | /config | Companion-only persistent Libation configuration and database. Contains account authorization material; never mount it into Shelfarr. |
LIBATION_BOOKS_DIR | /data | Completed backup output shared with Shelfarr for import. |
LIBATION_IN_PROGRESS_DIR | /config/in-progress | Private in-progress workspace. |
COMPANION_STATE_DIR | /config/shelfarr-companion | Bridge state and normalized cached export. |
COMPANION_TOKEN_FILE | /control/token | Companion side of the private shared token-file mount. |
COMPANION_MAX_ACTIVE_JOBS | 500 | Maximum queued plus running companion jobs; allowed range 1–10,000. |
COMPANION_MAX_TERMINAL_JOBS | 5000 | Maximum retained succeeded/failed companion job records; allowed range 100–100,000. |
COMPANION_TERMINAL_JOB_RETENTION_DAYS | 30 | Maximum age of succeeded/failed job records; allowed range 1–365 days. Active jobs are not pruned. |
ASPNETCORE_URLS | http://0.0.0.0:8080 | Internal listener. Connect it only to Shelfarr's private container network. |
⚠️
Before connecting Audible, run the unprivileged audiobook filesystem preflight in the
Audible Backup guide. mergerfs/libfuse mounts with a persistent
umask= option can force misleading reported modes and are rejected even when ordinary file writes work. Use the documented coordinated remount or verified complete underlying bind; do not run Shelfarr as root or bypass the check.
The first beta supports enable/test, external-browser sign-in, manual or scheduled sync, cached library browsing, individual-title backup, a confirmed and conservatively filtered existing-library batch, future-purchase automatic backup, and Library job status. Automation is disabled by default. Turning automatic backup off and on requires a new no-download baseline refresh; it does not start the existing-library action. An unfiltered Back up all, retroactive automatic backup, pause/resume, cancellation, and a targeted in-app purge of Shelfarr's cached Audible metadata and import history are not yet available. Disabling the connection does not erase those database records or an encrypted manual bridge token. See the complete Audible Backup guide for new and existing installation steps, retention, storage, security, version pinning, and Libation attribution.
Output Paths & Templates #
Where completed books are placed, and how their folders and filenames are named.
| Setting | Type | Default | Description |
audiobook_output_path | string | /audiobooks | Destination directory for completed audiobooks. |
ebook_output_path | string | /ebooks | Destination directory for completed ebooks. |
audiobook_path_template | string | {author}/{title} | Folder template for audiobooks. |
ebook_path_template | string | {author}/{title} | Folder template for ebooks. |
audiobook_filename_template | string | {author} - {title} | Filename template for audiobooks (extension appended automatically). |
ebook_filename_template | string | {author} - {title} | Filename template for ebooks (extension appended automatically). |
download_remote_path | string | (empty) | Download client host path, for remote path mapping. |
download_local_path | string | /downloads | Container-visible path where downloaded files appear. |
Template variables — available in both path and filename templates:
{author}Primary author
{authorSort}Sortable author
{title}Book title
{titleSort}Sortable title
{year}Publish year
{publisher}Publisher
{language}Language code
{series}Series name
{seriesSort}Sortable series
{seriesNum:00}Padded number
{narrator}Narrator
⚠️
Templates must include {title}. Optional suffix text is allowed inside braces, e.g.
{series/} or {series - }, which is dropped when the value is empty.
Path templates cannot contain .. or start with /.
Download Settings #
| Setting | Type | Default | Description |
preferred_download_types | json | ["torrent","usenet","direct"] | Download types in preference order. Higher-ranked types win when multiple result types are available. |
download_check_interval | integer | 60 | Seconds between download status checks. |
download_enqueue_timeout_minutes | integer | 5 | Minutes a download may stay queued before being flagged as never dispatched. |
post_processing_source_path_retries | integer | 10 | Retries while waiting for completed download files to appear. |
completed_download_import_mode | string | copy | copy retains the source but uses extra disk space; move removes the source and can stop torrent seeding; hardlink retains the source without duplicating data. Unsupported or cross-filesystem hardlinks fall back to copying. |
split_audiobook_bundle_imports | boolean | false | Split releases containing multiple self-contained M4B/AAX books into per-book folders. MP3, FLAC, and other chapter-based releases stay together. |
remove_completed_usenet_downloads | boolean | true | Remove completed usenet jobs from the client after import. |
i
Hardlink storage layout. The download source and library destination must be on one container-visible filesystem. With Docker, mount a shared parent such as /srv/media:/data into Shelfarr and the download client, then use paths such as /data/downloads, /data/audiobooks, and /data/ebooks. Separate mounts such as /downloads and /audiobooks can cross filesystem boundaries and prevent hardlinking. Unsupported or cross-filesystem hardlink attempts fall back to copying. Hardlinked source and library names reference the same content and share ownership and permissions, so content, ownership, or permission changes through either name affect both. The example Compose mounts remain suitable for the default copy mode; change the layout only when enabling hardlink.
Queue & Retry #
| Setting | Type | Default | Description |
immediate_search_enabled | boolean | false | Search immediately when a request is created, instead of waiting for the queue cycle. |
auto_approve_requests | boolean | false | Automatically enqueue searches for requests created by non-admin users. |
queue_batch_size | integer | 5 | Requests processed per queue run. |
rate_limit_delay | integer | 2 | Seconds between API calls. |
max_retries | integer | 10 | Retry attempts before a request is flagged for attention. |
retry_base_delay_hours | integer | 24 | Base delay before retrying not-found requests. |
retry_max_delay_days | integer | 7 | Maximum retry delay cap. |
Auto-Selection #
When enabled, Shelfarr picks the best result automatically instead of waiting for admin review.
| Setting | Type | Default | Description |
auto_select_enabled | boolean | false | Automatically select the best result without admin review. |
auto_select_min_seeders | integer | 1 | Minimum seeders required for torrent auto-selection. |
auto_select_confidence_threshold | integer | 90 | Minimum confidence score (0–100) for auto-selection. |
Comma-separated format lists. Approved/rejected lists gate auto-selection; preferred lists are ranked best→worst.
| Setting | Type | Default | Description |
ebook_preferred_formats | json | [] | Ebook formats in preference order, best to worst. |
ebook_approved_formats | json | [] | Ebook formats that may be auto-selected (blank = allow any). |
ebook_rejected_formats | json | [] | Ebook formats that must never be auto-selected. |
audiobook_preferred_formats | json | [] | Audiobook formats in preference order, best to worst. |
audiobook_approved_formats | json | [] | Audiobook formats that may be auto-selected (blank = allow any). |
audiobook_rejected_formats | json | [] | Audiobook formats that must never be auto-selected. |
audiobook_prefer_single_file | boolean | false | Prefer single-file releases (e.g. .m4b) over chapter-split releases. |
audiobook_prefer_higher_bitrate | boolean | false | Prefer higher bitrate releases when bitrate can be inferred from the title. |
Language & Matching #
| Setting | Type | Default | Description |
default_language | string | en | Default language for new requests. |
enabled_languages | json | ["en"] | Languages selectable when creating requests. |
min_match_confidence | integer | 50 | Minimum confidence score (0–100) for keeping results from category-less indexer searches. When nothing clears it, the best few low-confidence results are kept for manual review instead of returning an empty search. |
Notifications #
In-app notifications are always on. The events below are comma-separated: request_created, request_completed, request_failed, request_attention.
| Setting | Type | Default | Description |
discord_enabled | boolean | false | Send native Discord webhook notifications. |
discord_webhook_url | string | (empty) | Incoming Discord webhook URL for the target channel. |
discord_events | string | request_created,request_completed,request_failed,request_attention | Comma-separated Discord events to send. |
webhook_enabled | boolean | false | Send generic JSON webhook notifications. |
webhook_url | string | (empty) | Webhook endpoint URL. A JSON payload is sent per enabled event. |
webhook_token | string | (empty) | Optional Bearer token for webhook authentication. |
webhook_events | string | request_created,request_completed,request_failed,request_attention | Comma-separated webhook events to send. |
webhook_topic | string | (empty) | Optional topic field in the payload (required by ntfy on the base URL). |
telegram_enabled | boolean | false | Enable the Telegram command and notification integration. |
telegram_update_mode | string | polling | How updates are received: polling (local) or webhook (public HTTPS). |
telegram_bot_token | string | (empty) | Bot token from BotFather. |
telegram_bot_username | string | (empty) | Bot username without @. |
telegram_webhook_secret | string | (empty) | Secret checked against X-Telegram-Bot-Api-Secret-Token (webhook mode). |
telegram_allowed_chat_ids | string | (empty) | Fallback allowlist of group chat IDs. Prefer pairing-code approval. |
telegram_request_username | string | (empty) | Shelfarr username that owns Telegram group requests. Defaults to the first admin. |
telegram_notification_events | string | request_completed,request_failed,request_attention | Events sent back to the authorized group that created the request. |
Security #
| Setting | Type | Default | Description |
auth_disabled | boolean | false | Disable password auth (username-only, trusted networks only). Can also be set via DISABLE_AUTH. |
session_max_age_days | integer | 30 | Session lifetime before forced re-login. |
login_lockout_threshold | integer | 5 | Failed attempts before temporary lockout. |
login_lockout_duration_minutes | integer | 15 | Lockout duration in minutes. |
allow_user_uploads | boolean | false | Allow non-admin users to upload book files directly to fulfill requests. |
api_token | string | (generated) | Legacy global API token. Prefer per-user tokens from Profile → API tokens. |
OIDC / SSO Authentication #
Single sign-on via OpenID Connect — works with Authentik, Authelia, Keycloak and others.
| Setting | Type | Default | Description |
oidc_enabled | boolean | false | Enable OpenID Connect single sign-on. |
oidc_auto_redirect | boolean | false | Auto-start OIDC sign-in for unauthenticated users. Use /session/new?local=1 for the local form. |
oidc_provider_name | string | SSO | Display name shown on the login button. |
oidc_issuer | string | (empty) | Issuer URL (e.g. https://auth.example.com/realms/master). |
oidc_client_id | string | (empty) | Client ID from your identity provider. |
oidc_client_secret | string | (empty) | Client secret from your identity provider. |
oidc_scopes | string | openid profile email | Space-separated scopes to request. |
oidc_link_existing_users | boolean | false | Link an unlinked local user whose username matches the OIDC username or email prefix. |
oidc_auto_create_users | boolean | false | Auto-create new users on first OIDC login. |
oidc_default_role | string | user | Default role for auto-created users (user or admin). |
Health & Updates #
| Setting | Type | Default | Description |
health_check_interval | integer | 300 | Seconds between system health checks (default: 5 minutes). |
github_repo | string | Pedro-Revez-Silva/shelfarr | Repository used for update-availability checks. |