Create API-Reference wiki page with complete endpoint documentation

xpltd_admin 2026-04-03 22:41:10 -06:00
parent 3ef1e12be3
commit d22e0d89a5

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"
}
}
```