1 API-Reference
xpltd_admin edited this page 2026-04-03 22:41:10 -06:00

API Reference

Meta Value
Repo xpltdco/tubearr
Page API-Reference
Audience developers, agents
Last Updated 2026-04-04
Status current

Base URL

https://tubearr.xpltd.co/api/v1

Local development: http://localhost:8989/api/v1

Authentication

All API endpoints (except /ping) require authentication via one of:

Method Details
Same-origin Requests from the Tubearr UI (matching Origin/Referer header) are authenticated automatically
API Key header X-Api-Key: <your-api-key>
API Key query ?apikey=<your-api-key>

The API key is a UUID auto-generated on first startup. Retrieve or regenerate it via the System endpoints.

Unauthorized response:

{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "Invalid or missing API key"
}

Error Format

All errors return a consistent JSON structure:

{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Channel not found"
}

In development mode, a stack field may be included. API keys are always redacted from error responses.


Health & System

GET /ping

Liveness probe. No authentication required.

200 OK

GET /api/v1/health

Full health check with component status (database, yt-dlp, disk space, scheduler).

GET /api/v1/system/status

Runtime info: version, uptime, memory usage.

GET /api/v1/system/apikey

Returns the current API key.

POST /api/v1/system/apikey/regenerate

Generate a new API key. Returns the new key. The old key is immediately invalidated.

GET /api/v1/system/settings

Global settings (check interval, concurrent downloads).

PUT /api/v1/system/settings

Update global settings.

{
  "checkInterval": 360,
  "concurrentDownloads": 2
}

GET /api/v1/system/ytdlp/status

yt-dlp version and last update timestamp.

POST /api/v1/system/ytdlp/update

Force yt-dlp to self-update. Returns the new version string.


Channels

GET /api/v1/channel

List all monitored channels with content counts.

Response:

[
  {
    "id": 1,
    "name": "Example Channel",
    "platform": "youtube",
    "platformId": "UCxxxxxxx",
    "url": "https://youtube.com/@example",
    "monitoringEnabled": true,
    "monitoringMode": "all",
    "checkInterval": 360,
    "imageUrl": "https://...",
    "lastCheckedAt": "2026-04-04T10:00:00Z",
    "lastCheckStatus": "success",
    "contentCount": 42,
    "downloadedCount": 15
  }
]

POST /api/v1/channel

Add a channel by URL. Tubearr resolves metadata (name, image, subscriber count) via yt-dlp.

Request:

{
  "url": "https://youtube.com/@example",
  "monitoringMode": "future",
  "formatProfileId": 1
}

GET /api/v1/channel/:id

Get single channel with full metadata.

PUT /api/v1/channel/:id

Update channel settings.

{
  "name": "Updated Name",
  "checkInterval": 120,
  "formatProfileId": 2,
  "monitoringEnabled": true
}

PUT /api/v1/channel/:id/monitoring-mode

Change monitoring mode.

{
  "monitoringMode": "future"
}

Modes: all (grab everything), future (new content only), existing (backlog only), none (pause monitoring)

DELETE /api/v1/channel/:id

Delete channel. Cascades to all content items and queue items.

POST /api/v1/channel/scan-all

Manually trigger monitoring scan for all enabled channels. Returns immediately (202 Accepted); scans run in background.

POST /api/v1/channel/collect-all

Trigger back-catalog import for all channels with grabAllEnabled.


Content Items

GET /api/v1/content

Paginated content listing with filters.

Query parameters:

Param Type Description
page number Page number (default: 1)
limit number Items per page (default: 20)
status string Filter by status
contentType string Filter by type (video, audio, livestream)
search string Search by title
channelId number Filter by channel

GET /api/v1/channel/:id/content

Content items for a specific channel. Same pagination and filter params as above.

PATCH /api/v1/content/:id/monitored

Toggle monitoring state for a single content item.

{
  "monitored": false
}

PATCH /api/v1/content/bulk/monitored

Bulk toggle monitoring state.

{
  "ids": [1, 2, 3],
  "monitored": true
}

Download Queue

POST /api/v1/download/:contentItemId

Enqueue a content item for download. Returns 202 Accepted.

{
  "priority": 10
}

GET /api/v1/queue

List queue items. Optional ?status=pending|downloading|completed|failed|cancelled filter.

Response:

[
  {
    "id": 1,
    "contentItemId": 42,
    "status": "downloading",
    "priority": 0,
    "attempts": 1,
    "maxAttempts": 3,
    "error": null,
    "startedAt": "2026-04-04T10:05:00Z",
    "contentItem": {
      "title": "Example Video",
      "channelName": "Example Channel"
    }
  }
]

GET /api/v1/queue/:id

Get single queue item with content details.

POST /api/v1/queue

Alternative enqueue endpoint (accepts contentItemId in body).

DELETE /api/v1/queue/:id

Cancel a queue item (sets status to cancelled).

POST /api/v1/queue/:id/retry

Retry a failed queue item (resets to pending, increments attempts).


Format Profiles

GET /api/v1/format-profile

List all format profiles.

Response:

[
  {
    "id": 1,
    "name": "High Quality",
    "videoResolution": "1080p",
    "audioCodec": "opus",
    "audioBitrate": "192k",
    "containerFormat": "mkv",
    "isDefault": true,
    "embedSubtitles": true,
    "sponsorBlockRemove": "sponsor,selfpromo"
  }
]

POST /api/v1/format-profile

Create a format profile.

{
  "name": "Mobile Friendly",
  "videoResolution": "720p",
  "audioCodec": "aac",
  "audioBitrate": "128k",
  "containerFormat": "mp4",
  "embedSubtitles": false,
  "embedThumbnail": true
}

PUT /api/v1/format-profile/:id

Update a format profile.

DELETE /api/v1/format-profile/:id

Delete a format profile. Channels using it will have their formatProfileId set to NULL.


Notifications

GET /api/v1/notification

List notification channel configurations.

POST /api/v1/notification

Create a notification channel.

{
  "type": "discord",
  "name": "My Discord Server",
  "enabled": true,
  "config": {
    "webhookUrl": "<your-discord-webhook-url>"
  },
  "onGrab": true,
  "onDownload": true,
  "onFailure": true
}

PUT /api/v1/notification/:id

Update notification settings.

DELETE /api/v1/notification/:id

Delete a notification channel.

POST /api/v1/notification/:id/test

Send a test notification to verify configuration.


Platform Settings

GET /api/v1/platform-settings

Get per-platform settings for all platforms.

PUT /api/v1/platform-settings/:platform

Update settings for a specific platform (youtube, soundcloud, generic).

{
  "checkInterval": 240,
  "concurrencyLimit": 3,
  "rateLimitDelay": 2000,
  "defaultMonitoringMode": "future",
  "grabAllEnabled": false
}

Scan & Collect

POST /api/v1/scan/:channelId

Manually trigger a monitoring scan for a specific channel. Checks for new content and inserts it.

POST /api/v1/collect/:channelId

Trigger back-catalog import for a specific channel.


History

GET /api/v1/history

Download activity log with pagination.

Query parameters: page, limit, eventType

Event types: grabbed, downloaded, failed, imported, deleted


Playlists

GET /api/v1/playlist

List playlists discovered from monitored channels.


WebSocket

GET /ws

Upgrade to WebSocket connection for real-time events.

Events pushed to clients:

Event Description
download:progress Download percentage, speed, ETA for an active download
download:complete Download finished successfully
download:failed Download failed (includes error)
scan:start Channel monitoring scan started
scan:complete Channel monitoring scan finished
scan:new-content New content discovered during scan

Message format:

{
  "event": "download:progress",
  "data": {
    "contentItemId": 42,
    "percent": 45.2,
    "speed": "5.2MiB/s",
    "eta": "00:01:23"
  }
}