Create API-Reference wiki page with complete endpoint documentation
parent
3ef1e12be3
commit
d22e0d89a5
1 changed files with 457 additions and 0 deletions
457
API-Reference.-.md
Normal file
457
API-Reference.-.md
Normal file
|
|
@ -0,0 +1,457 @@
|
|||
# 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:**
|
||||
```json
|
||||
{
|
||||
"statusCode": 401,
|
||||
"error": "Unauthorized",
|
||||
"message": "Invalid or missing API key"
|
||||
}
|
||||
```
|
||||
|
||||
## Error Format
|
||||
|
||||
All errors return a consistent JSON structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"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.
|
||||
|
||||
```json
|
||||
{
|
||||
"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:**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"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:**
|
||||
```json
|
||||
{
|
||||
"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.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Updated Name",
|
||||
"checkInterval": 120,
|
||||
"formatProfileId": 2,
|
||||
"monitoringEnabled": true
|
||||
}
|
||||
```
|
||||
|
||||
### `PUT /api/v1/channel/:id/monitoring-mode`
|
||||
|
||||
Change monitoring mode.
|
||||
|
||||
```json
|
||||
{
|
||||
"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.
|
||||
|
||||
```json
|
||||
{
|
||||
"monitored": false
|
||||
}
|
||||
```
|
||||
|
||||
### `PATCH /api/v1/content/bulk/monitored`
|
||||
|
||||
Bulk toggle monitoring state.
|
||||
|
||||
```json
|
||||
{
|
||||
"ids": [1, 2, 3],
|
||||
"monitored": true
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Download Queue
|
||||
|
||||
### `POST /api/v1/download/:contentItemId`
|
||||
|
||||
Enqueue a content item for download. Returns **202 Accepted**.
|
||||
|
||||
```json
|
||||
{
|
||||
"priority": 10
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /api/v1/queue`
|
||||
|
||||
List queue items. Optional `?status=pending|downloading|completed|failed|cancelled` filter.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"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:**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"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.
|
||||
|
||||
```json
|
||||
{
|
||||
"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.
|
||||
|
||||
```json
|
||||
{
|
||||
"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`).
|
||||
|
||||
```json
|
||||
{
|
||||
"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:**
|
||||
```json
|
||||
{
|
||||
"event": "download:progress",
|
||||
"data": {
|
||||
"contentItemId": 42,
|
||||
"percent": 45.2,
|
||||
"speed": "5.2MiB/s",
|
||||
"eta": "00:01:23"
|
||||
}
|
||||
}
|
||||
```
|
||||
Loading…
Add table
Reference in a new issue