-
Notifications
You must be signed in to change notification settings - Fork 0
API
NeXroll provides a REST API for programmatic control of prerolls, categories, schedules, sequences, and more.
http://localhost:9393
Replace with your server's address if running remotely.
NeXroll supports two authentication methods:
Used by the web interface. After logging in via /auth/login, a session cookie is set and included in subsequent requests.
For programmatic access, use API keys with the /external/* endpoints:
Authorization: Bearer nx_your_api_key_hereOr as a query parameter:
GET /external/status?api_key=nx_your_api_key_hereAPI keys are generated in Settings → API Keys. Keys can be scoped as read-only or full access and can have expiration dates.
If authentication is not enabled in Settings, all internal API endpoints are accessible without credentials. External API endpoints always require a valid API key.
These endpoints are designed for external integrations and require an API key.
GET /external/statusReturns system status, connection info, and version.
GET /external/prerollsReturns all registered prerolls.
GET /external/schedulesReturns all schedules.
GET /external/active-schedulesReturns detailed info on currently active schedules.
GET /external/now-showingReturns the current active category, preroll string, and active schedules.
GET /external/categoriesReturns all categories with preroll counts.
GET /external/coming-soon?source=both&limit=10Returns upcoming movies/TV from NeX-Up.
| Parameter | Description | Default |
|---|---|---|
source |
movies, shows, or both
|
both |
limit |
Max items to return | 10 |
GET /external/sequencesReturns all saved sequences.
POST /external/sync-plexTriggers a Plex sync. Requires full access API key.
POST /external/categories
Content-Type: application/json
{
"name": "My Category",
"description": "Optional description"
}Requires full access API key.
POST /external/prerolls/register
Content-Type: application/json
{
"file_path": "/path/to/video.mp4",
"display_name": "My Preroll",
"category_id": 1
}Registers an existing video file as a preroll. Requires full access API key.
POST /external/prerolls/{preroll_id}/assign-category/{category_id}Requires full access API key.
POST /external/schedules
Content-Type: application/json
{
"name": "My Schedule",
"category_id": 1,
"start_date": "2025-12-01",
"end_date": "2025-12-25",
"exclusive": true,
"enabled": true
}Requires full access API key.
DELETE /external/schedules/{id}Requires full access API key.
PUT /external/schedules/{id}/toggleEnable or disable a schedule. Requires full access API key.
POST /external/apply-category/{category_id}Immediately applies a category to Plex. Requires full access API key.
GET /categoriesResponse:
[
{
"id": 1,
"name": "Christmas",
"description": "Holiday prerolls",
"plex_mode": "shuffle",
"preroll_count": 5
}
]POST /categories
Content-Type: application/json
{
"name": "Halloween",
"description": "Spooky prerolls"
}PUT /categories/{id}
Content-Type: application/json
{
"name": "Halloween 2025",
"description": "Updated description"
}DELETE /categories/{id}POST /categories/{id}/apply-to-plexImmediately applies the category's prerolls to Plex.
GET /categories/{id}/prerollsReturns all prerolls assigned to a category.
GET /prerollsResponse:
[
{
"id": 1,
"filename": "christmas_intro.mp4",
"display_name": "Christmas Intro",
"full_path": "/prerolls/christmas_intro.mp4",
"category_id": 1,
"tags": ["holiday", "winter"],
"duration": 15.5,
"file_size": 25000000
}
]POST /prerolls/upload
Content-Type: multipart/form-data
file: [binary]
category_id: 1
tags: "holiday,winter"
description: "My preroll"Limits: Maximum file size 500MB. Allowed extensions: .mp4, .mkv, .avi, .mov, .wmv, .flv, .webm, .m4v, .ts, .mpg, .mpeg.
PUT /prerolls/{id}
Content-Type: application/json
{
"display_name": "New Name",
"category_id": 2,
"tags": ["updated", "tags"]
}DELETE /prerolls/{id}POST /prerolls/check-duplicate
Content-Type: multipart/form-data
file: [binary]Returns whether a file with the same hash already exists.
GET /schedulesPOST /schedules
Content-Type: application/json
{
"name": "Christmas 2025",
"category_id": 1,
"start_date": "2025-12-01",
"end_date": "2025-12-25",
"exclusive": true,
"enabled": true
}PUT /schedules/{id}
Content-Type: application/json
{
"name": "Christmas 2025 Updated",
"enabled": false
}DELETE /schedules/{id}GET /schedules/activeReturns schedules currently active based on date/time.
GET /sequencesPOST /sequences
Content-Type: application/json
{
"name": "My Sequence",
"description": "Description here",
"blocks": [
{"type": "random", "category_id": 1, "count": 2}
]
}PUT /sequences/{id}
Content-Type: application/json
{
"name": "Updated Name",
"blocks": [...]
}DELETE /sequences/{id}POST /sequences/{id}/export?export_mode=with_community_idsExport modes: pattern_only, with_community_ids, with_preroll_data, full_bundle
POST /sequences/import
Content-Type: multipart/form-data
file: [.nexseq or .zip file]
auto_download: trueGET /settingsPUT /settings
Content-Type: application/json
{
"plex_url": "http://192.168.1.100:32400",
"plex_token": "your-token-here"
}POST /settings/test-plex
Content-Type: application/json
{
"url": "http://192.168.1.100:32400",
"token": "your-token"
}POST /settings/test-jellyfin
Content-Type: application/json
{
"url": "http://192.168.1.100:8096",
"api_key": "your-api-key"
}GET /settings/filler
PUT /settings/filler
Content-Type: application/json
{
"enabled": true,
"type": "category",
"category_id": 1
}Filler types: category, sequence, coming_soon
GET /path-mappingsPUT /path-mappings
Content-Type: application/json
{
"mappings": [
{
"nexroll_path": "/prerolls",
"plex_path": "/media/prerolls"
}
]
}GET /genre-mappingsPUT /genre-mappings
Content-Type: application/json
{
"genre": "Horror",
"category_id": 5
}GET /auth/statusReturns whether authentication is enabled and session info.
POST /auth/login
Content-Type: application/json
{
"username": "admin",
"password": "your-password",
"remember_me": false
}POST /auth/logoutPOST /auth/register
Content-Type: application/json
{
"username": "admin",
"password": "your-password",
"role": "admin"
}GET /auth/users # List all users
POST /auth/users # Create user
DELETE /auth/users/{user_id} # Delete user
PUT /auth/users/{user_id}/toggle # Enable/disable user
POST /auth/change-password # Change passwordGET /auth/settings # Get auth settings
PUT /auth/settings # Update auth settingsGET /auth/audit-logs # View authentication events
DELETE /auth/audit-logs # Clear audit logsGET /api/keys # List all API keys
POST /api/keys # Create new API key
PUT /api/keys/{key_id} # Update API key
DELETE /api/keys/{key_id} # Revoke API key
GET /api/keys/validate # Validate an API keyGET /logs?level=ERROR&category=scheduler&search=failed&limit=100| Parameter | Description |
|---|---|
level |
Filter by log level: DEBUG, INFO, WARNING, ERROR, CRITICAL |
category |
Filter by category: system, scheduler, api, user, plex, jellyfin, nexup |
search |
Search in log messages |
limit |
Max results to return |
GET /logs/statsReturns counts by level and category.
GET /logs/export?format=jsonFormats: json, csv
GET /logs/fileReturns the raw log file contents.
DELETE /logsGET /logs/settings
PUT /logs/settings
Content-Type: application/json
{
"log_level": "INFO",
"retention_days": 30,
"enable_db_logging": true,
"enable_request_logging": true,
"enable_scheduler_logging": true,
"enable_api_logging": true
}GET /nexup/settings # Get NeX-Up settings
PUT /nexup/settings # Update NeX-Up settingsPOST /nexup/radarr/connect # Connect to Radarr
DELETE /nexup/radarr/disconnect # Disconnect Radarr
GET /nexup/radarr/upcoming # Get upcoming moviesPOST /nexup/sonarr/connect # Connect to Sonarr
DELETE /nexup/sonarr/disconnect # Disconnect Sonarr
GET /nexup/sonarr/upcoming # Get upcoming showsPOST /nexup/preroll/generate # Generate dynamic intro
POST /nexup/preroll/generate-coming-soon-list # Generate Coming Soon List video
POST /nexup/preroll/generate-from-preview # Generate from preview settingsGET /nexup/sync-progress # Get current sync/download progressGET /healthResponse:
{
"status": "healthy",
"version": "1.11.0"
}GET /versionAll endpoints return errors in this format:
{
"detail": "Error message here"
}Common HTTP status codes:
| Code | Description |
|---|---|
200 |
Success |
201 |
Created |
400 |
Bad Request (invalid input) |
401 |
Unauthorized (missing or invalid credentials) |
403 |
Forbidden (insufficient permissions) |
404 |
Not Found |
413 |
Payload Too Large (file exceeds upload limit) |
500 |
Server Error |