Table of Contents
Configuration
| Meta | Value |
|---|---|
| Repo | xpltdco/tubearr |
| Page | Configuration |
| Audience | developers, agents |
| Last Updated | 2026-04-04 |
| Status | current |
Overview
All configuration is managed through environment variables, parsed in src/config/index.ts. In development, use a .env file (loaded via dotenv). In Docker, set variables in docker-compose.yml or pass them with -e.
Many settings can also be changed at runtime via the API (PUT /api/v1/system/settings) and are persisted in the systemConfig database table.
Environment Variables
Server
| Variable | Type | Default | Description |
|---|---|---|---|
TUBEARR_PORT |
number | 8989 |
HTTP server listen port |
NODE_ENV |
string | development |
development or production. Affects logging format, Vite middleware, yt-dlp auto-update |
TUBEARR_LOG_LEVEL |
string | info |
Fastify/Pino log level: trace, debug, info, warn, error, fatal |
Storage
| Variable | Type | Default | Description |
|---|---|---|---|
TUBEARR_DB_PATH |
string | ./data/tubearr.db |
Path to SQLite database file. In Docker: /config/tubearr.db |
TUBEARR_MEDIA_PATH |
string | ./media |
Root directory for downloaded media files. In Docker: /media |
TUBEARR_COOKIE_PATH |
string | ./data/cookies |
Directory for per-platform cookie files. In Docker: /config/cookies |
Authentication
| Variable | Type | Default | Description |
|---|---|---|---|
TUBEARR_API_KEY |
string | auto-generated UUID | API key for external access. If not set, a UUID is generated on first run and stored in the database |
Scheduling
| Variable | Type | Default | Description |
|---|---|---|---|
TUBEARR_SCHEDULER_ENABLED |
boolean | true |
Enable/disable the automatic channel monitoring scheduler |
TUBEARR_DEFAULT_CHECK_INTERVAL |
number | 360 |
Default channel check interval in minutes (6 hours) |
Rate Limiting
| Variable | Type | Default | Description |
|---|---|---|---|
TUBEARR_RATELIMIT_YOUTUBE_MS |
number | 1000 |
Minimum milliseconds between YouTube API requests |
TUBEARR_RATELIMIT_SOUNDCLOUD_MS |
number | 3000 |
Minimum milliseconds between SoundCloud API requests |
Concurrency
| Variable | Type | Default | Description |
|---|---|---|---|
TUBEARR_CONCURRENT_DOWNLOADS |
number | 2 |
Maximum number of simultaneous download tasks |
Runtime Settings (via API)
These settings can be changed without restarting the application:
| Setting | API Path | Stored In |
|---|---|---|
| Check interval | PUT /api/v1/system/settings |
systemConfig.check_interval |
| Concurrent downloads | PUT /api/v1/system/settings |
systemConfig.concurrent_downloads |
| Output path template | PUT /api/v1/system/settings |
systemConfig.app.output_template |
| NFO generation enabled | PUT /api/v1/system/settings |
systemConfig.app.nfo_enabled |
| Timezone | PUT /api/v1/system/settings |
systemConfig.app.timezone |
| Theme (dark/light) | PUT /api/v1/system/settings |
systemConfig.app.theme + localStorage |
| API key | POST /api/v1/system/apikey/regenerate |
systemConfig.api_key |
Media Server Settings (via API)
Configured through CRUD at /api/v1/media-servers:
| Setting | Description |
|---|---|
name |
Display name for the server |
type |
plex or jellyfin |
url |
Server base URL (e.g., http://192.168.1.100:32400) |
token |
Authentication token (redacted in API responses) |
librarySection |
Library section ID for targeted scans (Plex section ID or Jellyfin library ID) |
enabled |
Enable/disable auto-scan triggers |
Action endpoints:
POST /api/v1/media-servers/:id/test— Test connection to the media serverGET /api/v1/media-servers/:id/sections— List available library sections (Plex only)
Keyword Filters (via API)
Configured per-channel through PUT /api/v1/channel/:id:
| Field | Description |
|---|---|
includeKeywords |
Pipe-separated patterns — only matching titles are kept |
excludeKeywords |
Pipe-separated patterns — matching titles are filtered out |
Three pattern types are supported:
- Plain text — case-insensitive substring match (e.g.,
shorts) - Glob —
*wildcards, anchored to full title (e.g.,*tutorial*) - Regex —
/pattern/syntax, always case-insensitive (e.g.,/shorts|#shorts/)
Filters are applied during scheduled scans after dedup but before DB insertion.
Platform Settings (via API)
Per-platform defaults configured through PUT /api/v1/platform-settings/:platform:
| Setting | Description | Applies To |
|---|---|---|
checkInterval |
Default monitoring interval (minutes) | New channels on this platform |
concurrencyLimit |
Max concurrent operations | Rate-limited per platform |
rateLimitDelay |
Milliseconds between requests | API throttling |
defaultMonitoringMode |
Default mode for new channels | all, future, existing, none |
grabAllEnabled |
Enable back-catalog import | Collect endpoints |
grabAllOrder |
Import order | newest or oldest first |
scanLimit |
Max items per scan (default: 500) | Monitoring checks |
subtitleLanguages |
Default subtitle languages | Comma-separated codes |
defaultFormatProfileId |
Default quality profile | New downloads |
Format Profiles (via API)
Quality presets configured through POST/PUT /api/v1/format-profile:
| Option | Values | Description |
|---|---|---|
videoResolution |
best, 2160p, 1440p, 1080p, 720p, 480p, 360p |
Target video resolution |
audioCodec |
opus, aac, mp3, vorbis |
Preferred audio codec |
audioBitrate |
320k, 256k, 192k, 128k, 96k, 64k |
Audio quality |
containerFormat |
mp4, mkv, webm, mp3, opus, m4a |
Output container |
embedSubtitles |
boolean | Embed subtitles in media file |
subtitleLanguages |
string | Comma-separated language codes (e.g., en,es) |
embedChapters |
boolean | Embed chapter markers |
embedThumbnail |
boolean | Embed thumbnail in metadata |
sponsorBlockRemove |
string | Comma-separated SponsorBlock categories to auto-remove |
outputTemplate |
string | Per-profile output path template (e.g., {platform}/{channel}/{year}/{title}.{ext}) |
Output Path Template Variables: {platform}, {channel}, {title}, {ext}, {year}, {month}, {day}, {contentType}, {id}
SponsorBlock categories: sponsor, selfpromo, interaction, intro, outro, preview, music_offtopic, filler
Content Ratings
Ratings can be set per-channel (default for all content) or per-item (overrides channel default). Available ratings: TV-Y, TV-Y7, TV-G, TV-PG, TV-14, TV-MA, G, PG, PG-13, R, NC-17, NR. Ratings are written into NFO sidecar files for media server library categorization.
Notification Channels (via API)
Configured through POST/PUT /api/v1/notification:
Discord
{
"type": "discord",
"config": {
"webhookUrl": "<your-discord-webhook-url>"
}
}
{
"type": "email",
"config": {
"smtpHost": "smtp.example.com",
"smtpPort": 587,
"username": "<your-email>",
"password": "<your-password>",
"to": "recipient@example.com"
}
}
Pushover
{
"type": "pushover",
"config": {
"userKey": "<your-user-key>",
"apiToken": "<your-api-token>"
}
}
Telegram
{
"type": "telegram",
"config": {
"botToken": "<your-bot-token>",
"chatId": "<your-chat-id>"
}
}
Each notification channel has event toggles: onGrab, onDownload, onFailure.
RSS Feed
A podcast-compatible RSS 2.0 feed is available at /api/v1/feed/rss (public, no auth required). The feed includes all downloaded audio content with enclosure links to /api/v1/media/:id/:filename (also public). Subscribe in any podcast app to receive downloaded audio as episodes.
Docker Environment Defaults
When running in Docker (set automatically by the Dockerfile):
| Variable | Docker Default |
|---|---|
NODE_ENV |
production |
TUBEARR_DB_PATH |
/config/tubearr.db |
TUBEARR_MEDIA_PATH |
/media |
TUBEARR_COOKIE_PATH |
/config/cookies |
Example .env File
# Server
TUBEARR_PORT=8989
NODE_ENV=development
TUBEARR_LOG_LEVEL=info
# Storage
TUBEARR_DB_PATH=./data/tubearr.db
TUBEARR_MEDIA_PATH=./media
TUBEARR_COOKIE_PATH=./data/cookies
# Auth (optional — auto-generated if not set)
# TUBEARR_API_KEY=your-uuid-here
# Scheduling
TUBEARR_SCHEDULER_ENABLED=true
TUBEARR_DEFAULT_CHECK_INTERVAL=360
# Rate limiting
TUBEARR_RATELIMIT_YOUTUBE_MS=1000
TUBEARR_RATELIMIT_SOUNDCLOUD_MS=3000
# Concurrency
TUBEARR_CONCURRENT_DOWNLOADS=2