Skip to content

REST API

The Fast Video Cataloger Server provides a comprehensive REST API for integration with external applications and custom clients. The API uses JSON for request and response bodies.

API Documentation

Interactive API documentation is available via Swagger UI at:

http://your-server:8754/api/docs

The OpenAPI 3.0 specification is available at:

http://your-server:8754/swagger/v1/swagger.json

Base URL

All API endpoints are prefixed with /api/v1/.

Authentication

Most endpoints require authentication. Include the session token in requests using either:

Authorization Header (recommended):

Authorization: Bearer {token}

Query String:

/api/v1/videos?token={token}

To obtain a token, use the login endpoint (see Authentication section below).

Roles

The API supports three user roles:

Role Permissions
Viewer Read-only access to all resources
Editor Read and write access (create, update, delete)
Admin Full access including user management

Authentication Endpoints

Check if Authentication Required

GET /api/v1/auth/required

Returns whether authentication is required for this server.

Response:

{
  "authenticationRequired": true
}

Login

POST /api/v1/auth/login

Authenticate and obtain a session token.

Request Body:

{
  "username": "user@example.com",
  "password": "yourpassword"
}

Response:

{
  "success": true,
  "token": "session-token-string",
  "expiresAt": "2024-01-15T12:00:00Z",
  "role": "Editor"
}

Logout

POST /api/v1/auth/logout

Invalidate the current session token.

Get Session Info

GET /api/v1/auth/session

Get information about the current session.

Response:

{
  "isAuthenticated": true,
  "userId": 1,
  "username": "user@example.com",
  "role": "Editor"
}

Videos

Search Videos

GET /api/v1/videos

Search and list videos with optional filters.

Query Parameters:

Parameter Type Description
search string Text search query
keywords string Comma-separated keyword filter
title string Filter by title
genre int Filter by genre ID
minRating int Minimum rating (0-5)
maxRating int Maximum rating (0-5)
offset int Pagination offset (default: 0)
limit int Max results

Response:

{
  "success": true,
  "data": [...],
  "totalCount": 150
}

Get Video

GET /api/v1/videos/{id}

Get details for a specific video.

Get Video Preview Image

GET /api/v1/videos/{id}/image

Returns the video preview image as JPEG binary data.

Stream Video

GET /api/v1/videos/{id}/stream

Stream video content. Supports HTTP Range headers for seeking.

Get Video Thumbnails

GET /api/v1/videos/{id}/thumbnails

Get all scene thumbnails for a video.

Query Parameters:

Parameter Type Description
includeImageData bool Include base64 image data (default: false)

Get Video Actors

GET /api/v1/videos/{id}/actors

Get all actors appearing in a video.

Get Video Tags

GET /api/v1/videos/{id}/tags

Get all tags applied to a video.

Get Random Videos

GET /api/v1/videos/random

Get random videos from the catalog.

Query Parameters:

Parameter Type Description
count int Number of videos to return (default: 10)

Get Videos Pending Indexing

GET /api/v1/videos/pending-indexing

Get videos that need indexing (no length or no thumbnails).

Batch Get Videos

POST /api/v1/videos/batch

Get multiple videos by ID in a single request. Efficient for avoiding N+1 query patterns.

Request Body:

[1, 2, 3, 4, 5]

Add Video (Editor)

POST /api/v1/videos

Add a new video to the catalog.

Request Body:

{
  "path": "/path/to/video.mp4",
  "title": "Video Title",
  "description": "Description",
  "genre": 1,
  "rating": 4,
  "lengthSeconds": 3600,
  "link": "https://example.com"
}

Update Video (Editor)

PUT /api/v1/videos/{id}

Update video properties.

Request Body:

{
  "title": "New Title",
  "description": "New Description",
  "rating": 5,
  "genre": 2,
  "link": "https://example.com"
}

Delete Video (Editor)

DELETE /api/v1/videos/{id}

Delete a video from the catalog.

Update Video Path (Editor)

PUT /api/v1/videos/{id}/path

Change the file path of a video.

Request Body:

{
  "newPath": "/new/path/to/video.mp4"
}

Set Video Image (Editor)

PUT /api/v1/videos/{id}/image

Set the video preview image. Request body is raw JPEG bytes.

Set Video Genre (Editor)

PUT /api/v1/videos/{id}/genre?genre={genreName}

Set the video genre by name.

Set Video Rating (Editor)

PUT /api/v1/videos/{id}/rating

Request Body:

{
  "rating": 4
}

Tag Video (Editor)

PUT /api/v1/videos/{id}/tags

Request Body:

{
  "tags": "action, drama, thriller"
}

Remove Tag from Video (Editor)

DELETE /api/v1/videos/{id}/tags/{tagInstanceId}

Add Actor to Video (Editor)

POST /api/v1/videos/{id}/cast/{actorId}

Remove Actor from Video (Editor)

DELETE /api/v1/videos/{id}/cast/{actorId}

Get Video Companion Images

GET /api/v1/videos/{id}/images

Get companion images associated with a video.

Remove Video Companion Image (Editor)

DELETE /api/v1/videos/{id}/images/{imageId}

Get Video Cover Images

GET /api/v1/videos/{id}/covers

Get front and back cover images for a video.

Set Video Cover Images (Editor)

PUT /api/v1/videos/{id}/covers

Request Body:

{
  "frontCoverId": 123,
  "backCoverId": 456
}

Get Video Extended Properties

GET /api/v1/videos/{id}/properties

Get custom extended properties for a video.

Set Video Extended Property (Editor)

PUT /api/v1/videos/{id}/properties

Request Body:

{
  "propertyName": "CustomField",
  "value": "Custom Value"
}

Get Video Archives

GET /api/v1/videos/{id}/archives

Get archive IDs containing this video.

Archive Video (Editor)

POST /api/v1/videos/{id}/archive

Request Body:

{
  "archiveId": 1
}

Actors

Search Actors

GET /api/v1/actors

Query Parameters:

Parameter Type Description
search string Text search query
firstName string Filter by first name
lastName string Filter by last name
tags string Comma-separated tag filter
skipImageData bool Skip portrait data (default: true)
limit int Max results

Get All Actors

GET /api/v1/actors/all

Get Actor

GET /api/v1/actors/{id}

Get Actor Portrait

GET /api/v1/actors/{id}/portrait

Returns portrait image as JPEG binary data.

Get Actor Tags

GET /api/v1/actors/{id}/tags

Get Actor Companion Images

GET /api/v1/actors/{id}/images

Create Actor (Editor)

POST /api/v1/actors

Request Body:

{
  "firstName": "John",
  "lastName": "Doe",
  "bio": "Actor biography",
  "link": "https://example.com"
}

Update Actor (Editor)

PUT /api/v1/actors/{id}

Delete Actor (Editor)

DELETE /api/v1/actors/{id}

Tag Actor (Editor)

POST /api/v1/actors/{id}/tags

Request Body:

{
  "tags": "lead, supporting"
}

Remove Actor Tag (Editor)

DELETE /api/v1/actors/{id}/tags/{tagInstanceId}

Remove Actor Companion Image (Editor)

DELETE /api/v1/actors/{id}/images/{imageId}

Get Actor Face Embedding

GET /api/v1/actors/{id}/embedding

Get face recognition embedding data for an actor.

Save Actor Face Embedding (Editor)

PUT /api/v1/actors/{id}/embedding

Request Body:

{
  "embeddingData": "base64-encoded-embedding"
}

Delete Actor Face Embedding (Editor)

DELETE /api/v1/actors/{id}/embedding

Tags

Get Video Tags

GET /api/v1/tags/video

Get all video tag definitions.

Get Thumbnail Tags

GET /api/v1/tags/thumbnail

Get all scene/thumbnail tag definitions.

Get Actor Tags

GET /api/v1/tags/actor

Get all actor tag definitions.

Get Tag Groups

GET /api/v1/tags/groups

Get all tag groups.

Get Video Tags in Group

GET /api/v1/tags/groups/{groupId}/video

Get Thumbnail Tags in Group

GET /api/v1/tags/groups/{groupId}/thumbnail

Get Genres

GET /api/v1/tags/genres

Get all genre definitions.

Create Video Tag (Editor)

POST /api/v1/tags

Request Body:

{
  "name": "Action",
  "parentId": null,
  "color": 16711680,
  "description": "Action scenes",
  "link": ""
}

Update Video Tag (Editor)

PUT /api/v1/tags/{id}

Delete Video Tag (Editor)

DELETE /api/v1/tags/{id}

Delete Thumbnail Tag (Editor)

DELETE /api/v1/tags/thumbnail/{id}

Create Tag Group (Editor)

POST /api/v1/tags/groups

Request Body:

{
  "name": "My Group"
}

Rename Tag Group (Editor)

PUT /api/v1/tags/groups/{id}

Request Body:

{
  "name": "New Name"
}

Delete Tag Group (Editor)

DELETE /api/v1/tags/groups/{id}

Add Tag to Group (Editor)

POST /api/v1/tags/groups/{groupId}/tags/{tagId}

Remove Tag from Group (Editor)

DELETE /api/v1/tags/groups/{groupId}/tags/{tagId}

Get Video Tag Usage

GET /api/v1/tags/{id}/usage

Get count of videos using this tag.

Get Thumbnail Tag Usage

GET /api/v1/tags/thumbnail/{id}/usage

Get Actor Tag Usage

GET /api/v1/tags/actor/{id}/usage

Rename Genre (Editor)

PUT /api/v1/tags/genres

Request Body:

{
  "oldName": "Old Genre",
  "newName": "New Genre"
}

Bins (Collections)

Get All Bins

GET /api/v1/bins

Get Child Bins

GET /api/v1/bins/{id}/bins

Get bins nested within a bin.

Get Videos in Bin

GET /api/v1/bins/{id}/videos

Get Bin Query

GET /api/v1/bins/{id}/query

Get the smart bin query (for dynamic bins).

Create Bin (Editor)

POST /api/v1/bins

Request Body:

{
  "label": "My Collection",
  "parentId": null,
  "color": 255
}

Update Bin (Editor)

PUT /api/v1/bins/{id}

Request Body:

{
  "label": "New Label",
  "color": 16711680
}

Delete Bin (Editor)

DELETE /api/v1/bins/{id}

Set Bin Query (Editor)

PUT /api/v1/bins/{id}/query

Set a VideoQuery to make this a smart/dynamic bin.

Add Video to Bin (Editor)

POST /api/v1/bins/{id}/videos

Request Body:

{
  "videoId": 123
}

Remove Video from Bin (Editor)

DELETE /api/v1/bins/{id}/videos/{videoId}

Thumbnails (Scenes)

Search Thumbnails

GET /api/v1/thumbnails/search

Query Parameters:

Parameter Type Description
keywords string Comma-separated keyword filter
search string Text search query
videoId long Filter by video ID
limit int Max results

Get Thumbnail

GET /api/v1/thumbnails/{id}

Get thumbnail entry metadata.

Get Thumbnail Image

GET /api/v1/thumbnails/{id}/image

Returns scene image as JPEG binary data.

Get Thumbnail Tags

GET /api/v1/thumbnails/{id}/tags

Get Thumbnail Extended Properties

GET /api/v1/thumbnails/{id}/properties

Add Thumbnail (Editor)

POST /api/v1/thumbnails

Request Body:

{
  "videoId": 123,
  "timeMs": 5000,
  "imageData": "base64-encoded-jpeg"
}

Delete Thumbnail (Editor)

DELETE /api/v1/thumbnails/{id}

Tag Thumbnail (Editor)

POST /api/v1/thumbnails/{id}/tags

Request Body:

{
  "tags": "outdoor, sunny"
}

Remove Thumbnail Tag (Editor)

DELETE /api/v1/thumbnails/{id}/tags/{tagInstanceId}

Set Thumbnail Extended Property (Editor)

PUT /api/v1/thumbnails/{id}/properties

Request Body:

{
  "propertyName": "CustomField",
  "value": "Custom Value"
}

Get Thumbnail Classifications

GET /api/v1/thumbnails/{id}/classifications

Get AI scene classifications for a thumbnail.

Save Thumbnail Classification (Editor)

POST /api/v1/thumbnails/{id}/classifications

Request Body:

{
  "label": "outdoor",
  "confidence": 0.95
}

Delete Thumbnail Classifications (Editor)

DELETE /api/v1/thumbnails/{id}/classifications

Clips

Create Clip (Editor)

POST /api/v1/clips

Request Body:

{
  "videoId": 123,
  "startMs": 10000,
  "endMs": 20000
}

Get Clip

GET /api/v1/clips/{id}

Delete Clip (Editor)

DELETE /api/v1/clips/{id}

Playlists

Get All Playlists

GET /api/v1/playlists

Create Playlist (Editor)

POST /api/v1/playlists

Request Body:

{
  "name": "My Playlist"
}

Delete Playlist (Editor)

DELETE /api/v1/playlists/{id}

Get Playlist Clip IDs

GET /api/v1/playlists/{id}/clips

Get Playlist Clip at Index

GET /api/v1/playlists/{id}/clips/{index}

Add Clip to Playlist (Editor)

POST /api/v1/playlists/{id}/clips

Request Body:

{
  "clipId": 123,
  "index": 0
}

Remove Clip from Playlist (Editor)

DELETE /api/v1/playlists/{id}/clips/{index}

Subtitles

Get Video Subtitles

GET /api/v1/videos/{videoId}/subtitles

Get all subtitles for a video.

Create Subtitle (Editor)

POST /api/v1/videos/{videoId}/subtitles

Request Body:

{
  "startMs": 1000,
  "endMs": 5000,
  "text": "Hello, world!"
}

Delete All Video Subtitles (Editor)

DELETE /api/v1/videos/{videoId}/subtitles

Get Subtitle

GET /api/v1/subtitles/{id}

Delete Subtitle (Editor)

DELETE /api/v1/subtitles/{id}

Search Subtitles

GET /api/v1/subtitles/search

Query Parameters:

Parameter Type Description
search string Text to search for
offset int Pagination offset
limit int Max results

Archives

Get All Archives

GET /api/v1/archives

Get Archive

GET /api/v1/archives/{id}

Create Archive (Editor)

POST /api/v1/archives

Request Body:

{
  "name": "Backup 2024",
  "description": "Annual backup",
  "location": "External Drive A"
}

Update Archive (Editor)

PUT /api/v1/archives/{id}

Delete Archive (Editor)

DELETE /api/v1/archives/{id}

Scene Classifications

Get Distinct Labels

GET /api/v1/classifications/labels

Get all unique scene classification labels in the catalog.

Search by Label

GET /api/v1/classifications/search

Query Parameters:

Parameter Type Description
label string Classification label to search
minConfidence double Minimum confidence score (0-1)
offset int Pagination offset
limit int Max results

Get Video Classifications

GET /api/v1/classifications/video/{videoId}

Get all scene classifications for thumbnails in a video.


Properties (Metadata)

Get Property Metadata

GET /api/v1/properties/meta/{property}

Get metadata definitions for a custom property.

Set Property Metadata (Editor)

POST /api/v1/properties/meta

Request Body:

{
  "property": "MyCustomField",
  "aspect": "type",
  "value": "text"
}

Delete Property Metadata (Editor)

DELETE /api/v1/properties/meta

Request Body:

{
  "property": "MyCustomField",
  "aspect": "type"
}

Statistics

Get Combined Stats

GET /api/v1/stats

Get combined catalog statistics.

Response:

{
  "success": true,
  "data": {
    "videoCount": 1500,
    "actorCount": 250,
    "imageCount": 5000,
    "thumbnailCount": 0
  }
}

Get Video Count

GET /api/v1/stats/videos

Get Actor Count

GET /api/v1/stats/actors

Get Image Count

GET /api/v1/stats/images

Get Thumbnail Count

GET /api/v1/stats/thumbnails

Uploads

Upload Video (Editor)

POST /api/v1/upload/video

Upload a video file using multipart/form-data.

Request: - Content-Type: multipart/form-data - Field: file - The video file

Response:

{
  "success": true,
  "uploadId": 123
}

Complete Video Upload (Editor)

POST /api/v1/upload/video/{uploadId}/complete

Finalize upload and add video to catalog.

Request Body:

{
  "title": "Video Title",
  "description": "Description",
  "genre": 1,
  "rating": 4,
  "link": ""
}

Cancel Upload (Editor)

DELETE /api/v1/upload/video/{uploadId}

Cancel upload and delete temporary files.

Upload Image (Editor)

POST /api/v1/upload/image

Upload an image file, optionally as a companion image for a video.

Form Fields: - file - The image file - videoId (optional) - Associate as companion image


Response Format

All API responses use a consistent wrapper format:

Success Response

{
  "success": true,
  "data": { ... },
  "totalCount": 100
}

Error Response

{
  "success": false,
  "error": "Error message description"
}

Simple Result Response

For operations that don't return data:

{
  "success": true,
  "message": "Operation completed successfully"
}

HTTP Status Codes

Code Description
200 Success
400 Bad Request - Invalid parameters
401 Unauthorized - Authentication required
403 Forbidden - Insufficient permissions (requires Editor/Admin)
404 Not Found - Resource not found
500 Server Error - Internal error
503 Service Unavailable - Catalog not available

CORS

The API supports Cross-Origin Resource Sharing (CORS) to allow web clients from any origin.


Rate Limiting

Currently, no rate limiting is enforced. Clients should implement reasonable request throttling to avoid overloading the server.


Version History

Version Date Changes
2.0 2024 Full API implementation with 80+ endpoints covering all catalog functionality
1.0 2023 Initial REST API with basic read operations