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:
The OpenAPI 3.0 specification is available at:
Connecting an AI assistant
You do not have to write an HTTP client for that. Fast Video Cataloger ships an MCP server that exposes the catalog as ready-made tools - see Connect an AI Assistant.
Automating the application itself
This API is headless - it reaches the catalog, not the program. To drive the selection, the GUI or the video player, use the C# scripting API from the Script Console instead.
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):
Query String:
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 |
API Keys¶
Session tokens expire after eight hours, which is fine for a browser but not for a script, a scheduled job or an AI assistant. For those, create an API key: a long-lived credential with its own role that is presented exactly like a session token.
An administrator creates keys through the API keys endpoints (see below), or without any password in the desktop application that shares the catalog: Start > Server > Manage Users (shown once the server is running) > "Create key...". That button is the easiest way to create the first key on a fresh setup, since the desktop application is already connected to its own server as the administrator. The key is shown once, in the response that creates it. Only a hash is stored, so a lost key cannot be recovered - create a new one and revoke the old.
Active keys (not revoked, not expired) are limited to the number of user accounts the server's license allows; creating one beyond that returns 403 with the numbers. Revoke a key to free its slot.
Give each key the least privilege that does the job. A key that only needs to search the catalog should be a Viewer; a key cannot be given more privilege than the user who owns it, and it stops working if that user is deleted or deactivated.
Change the default admin password
Every catalog gets a built-in admin account with the password admin the first time it is opened, so authentication is enforced from the start — but until that password is changed, anyone who can reach the port can log in as the administrator with it. Change it before making the server reachable beyond your own machine. See Authentication and Users.
Authentication Endpoints¶
Check if Authentication Required¶
Returns whether authentication is required for this server.
Response:
Login¶
Authenticate and obtain a session token.
Request Body:
Response:
{
"success": true,
"token": "session-token-string",
"expiresAt": "2024-01-15T12:00:00Z",
"role": "Editor"
}
Logout¶
Invalidate the current session token.
Get Session Info¶
Get information about the current session.
Response:
API Keys¶
Long-lived credentials for machine clients. All three endpoints require the Admin role.
Create API Key (Admin)¶
Request Body:
role defaults to Viewer. Omit expiresInDays for a key that never expires.
Response:
{
"success": true,
"data": {
"id": 3,
"name": "editing workstation agent",
"role": "Viewer",
"createdAt": "2026-08-08T09:12:00Z",
"expiresAt": "2027-08-08T09:12:00Z",
"isActive": true,
"key": "fvc_XCJ1s..."
}
}
The key field appears in this response and nowhere else. Store it before moving on.
Use it exactly like a session token:
List API Keys (Admin)¶
Returns the metadata of every key - name, role, when it was created, and when it was last used. The keys themselves are not stored and are never returned.
Revoke API Key (Admin)¶
Deletes the key. It stops working on the next request made with it.
Videos¶
Search Videos¶
Search and list videos with optional filters.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
search |
string | Text search query |
keywords |
string | Comma-separated keyword filter |
matchAllKeywords |
bool | When true a video must carry every keyword in keywords, not just one of them (default false) |
actors |
string | Comma-separated actor ids; only videos whose cast includes them are returned - the reverse of GET /videos/{id}/actors |
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:
Get Video¶
Get details for a specific video.
Get Video Preview Image¶
Returns the video preview image as JPEG binary data.
Stream Video¶
Stream video content. Supports HTTP Range headers for seeking.
Get Video Thumbnails¶
Accepts limit and offset. Without them every thumbnail is returned, which for a long video is a large response. totalCount always reports the full number.
Get all scene thumbnails for a video.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
includeImageData |
bool | Include base64 image data (default: false) |
Get Video Actors¶
Get all actors appearing in a video.
Get Video Tags¶
Get all tags applied to a video.
Get Random Videos¶
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 videos that need indexing (no length or no thumbnails).
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
limit |
int | Max results |
offset |
int | Pagination offset |
A newly added folder can leave thousands of entries pending, and each one is a full
record — page through them rather than asking for the lot. totalCount in the response
is the real total, so you can tell how much is left.
Batch Get Videos¶
Get multiple videos by ID in a single request. Efficient for avoiding N+1 query patterns.
Request Body:
Add Video (Editor)¶
Add a new video to the catalog. This creates the catalog entry only - it has no thumbnails and no duration until the video is indexed.
Request Body:
{
"path": "/path/to/video.mp4",
"title": "Video Title",
"description": "Description",
"genre": 1,
"rating": 4,
"lengthSeconds": 3600,
"link": "https://example.com"
}
Index Video (Editor)¶
Index a video that is already in the catalog. Extracts thumbnails and duration, and applies whatever else the server is configured for - file metadata, transcription, face recognition and scene classification.
Indexing a video takes minutes, so the call returns 202 Accepted as soon as the work is queued and continues in the background. Poll GET /api/v1/videos/{id}/thumbnails to follow progress, or GET /api/v1/videos/pending-indexing to see what is still outstanding.
Only one video is indexed at a time. Further requests queue and run in turn, so it is safe to loop over pending-indexing and post each id.
Response:
Returns 404 if the video is not in the catalog, or if its file cannot be found on the server.
Update Video (Editor)¶
Update video properties.
Request Body:
{
"title": "New Title",
"description": "New Description",
"rating": 5,
"genre": 2,
"link": "https://example.com"
}
Delete Video (Editor)¶
Delete a video from the catalog.
Update Video Path (Editor)¶
Change the file path of a video.
Request Body:
Set Video Image (Editor)¶
Set the video preview image. Request body is raw JPEG bytes.
Set Video Genre (Editor)¶
Set the video genre by name.
Set Video Rating (Editor)¶
Request Body:
Tag Video (Editor)¶
Request Body:
Remove Tag from Video (Editor)¶
Add Actor to Video (Editor)¶
Remove Actor from Video (Editor)¶
Get Video Companion Images¶
Get companion images associated with a video.
Remove Video Companion Image (Editor)¶
Get Video Cover Images¶
Get front and back cover images for a video.
Set Video Cover Images (Editor)¶
Request Body:
Get Video Extended Properties¶
Get custom extended properties for a video.
Set Video Extended Property (Editor)¶
Request Body:
This sets the value on the video only. For the property to show up in the client's
search filter and property lists it must also be registered once with
POST /api/v1/properties/meta (see Properties (Metadata) below).
Get Video Archives¶
Get archive IDs containing this video.
Archive Video (Editor)¶
Request Body:
Actors¶
Search 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 Actor¶
Get Actor Portrait¶
Returns portrait image as JPEG binary data.
Get Actor Tags¶
Get Actor Companion Images¶
Create Actor (Editor)¶
Request Body:
Update Actor (Editor)¶
Delete Actor (Editor)¶
Tag Actor (Editor)¶
Request Body:
Remove Actor Tag (Editor)¶
Remove Actor Companion Image (Editor)¶
Get Actor Face Embedding¶
Get face recognition embedding data for an actor.
Save Actor Face Embedding (Editor)¶
Request Body:
Delete Actor Face Embedding (Editor)¶
Tags¶
Get Video Tags¶
Get all video tag definitions.
Get Thumbnail Tags¶
Get all scene/thumbnail tag definitions.
Get Actor Tags¶
Get all actor tag definitions.
Get Tag Groups¶
Get all tag groups.
Get Video Tags in Group¶
Get Thumbnail Tags in Group¶
Get Genres¶
Get all genre definitions.
Create Video Tag (Editor)¶
Request Body:
{
"name": "Action",
"parentId": null,
"color": 16711680,
"description": "Action scenes",
"link": ""
}
Update Video Tag (Editor)¶
Delete Video Tag (Editor)¶
Delete Thumbnail Tag (Editor)¶
Create Tag Group (Editor)¶
Request Body:
Rename Tag Group (Editor)¶
Request Body:
Delete Tag Group (Editor)¶
Add Tag to Group (Editor)¶
Remove Tag from Group (Editor)¶
Get Video Tag Usage¶
Get count of videos using this tag.
Get Thumbnail Tag Usage¶
Get Actor Tag Usage¶
Rename Genre (Editor)¶
Request Body:
Bins (Collections)¶
Get All Bins¶
Get Child Bins¶
Get bins nested within a bin.
Get Videos in Bin¶
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
limit |
int | Max results |
offset |
int | Pagination offset |
A bin can hold the whole catalog, so page large bins. totalCount is the full size of
the bin regardless of how many records were returned.
Get Bin Query¶
Get the smart bin query (for dynamic bins).
Create Bin (Editor)¶
Request Body:
Update Bin (Editor)¶
Request Body:
Delete Bin (Editor)¶
Set Bin Query (Editor)¶
Set a VideoQuery to make this a smart/dynamic bin.
Add Video to Bin (Editor)¶
Request Body:
Remove Video from Bin (Editor)¶
Thumbnails (Scenes)¶
Search Thumbnails¶
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 thumbnail entry metadata.
Get Thumbnail Image¶
Returns scene image as JPEG binary data.
Get Thumbnail Tags¶
Get Thumbnail Extended Properties¶
Add Thumbnail (Editor)¶
Request Body:
Delete Thumbnail (Editor)¶
Tag Thumbnail (Editor)¶
Request Body:
Remove Thumbnail Tag (Editor)¶
Set Thumbnail Extended Property (Editor)¶
Request Body:
Get Thumbnail Classifications¶
Get AI scene classifications for a thumbnail.
Save Thumbnail Classification (Editor)¶
Request Body:
Delete Thumbnail Classifications (Editor)¶
Clips¶
Create Clip (Editor)¶
Request Body:
Get Clip¶
Delete Clip (Editor)¶
Playlists¶
Get All Playlists¶
Create Playlist (Editor)¶
Request Body:
Delete Playlist (Editor)¶
Get Playlist Clip IDs¶
Get Playlist Clip at Index¶
Add Clip to Playlist (Editor)¶
Request Body:
Remove Clip from Playlist (Editor)¶
Subtitles¶
Get Video Subtitles¶
Get the transcript of a video as timed lines.
Accepts limit and offset. Without them the whole transcript is returned - a feature-length one is a few hundred kilobytes of JSON - while totalCount always reports the full number of lines.
Create Subtitle (Editor)¶
Request Body:
Delete All Video Subtitles (Editor)¶
Get Subtitle¶
Delete Subtitle (Editor)¶
Search Subtitles¶
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
search |
string | Text to search for |
offset |
int | Pagination offset |
limit |
int | Max results |
Returns the IDs of the matching subtitle lines — not video IDs. Resolve each one
with GET /api/v1/subtitles/{id} to get its text, its videoFileID and its start and end
time:
GET /api/v1/subtitles/search?search=launch
{"success":true,"data":[133,208,342,391,827]}
GET /api/v1/subtitles/133
{"success":true,"data":{"id":133,"videoFileID":2,"startTime":271.62,"endTime":276.34,
"text":"...along with the Gateway and the Space Launch System"}}
Passing these IDs to an endpoint that expects a video ID will silently return the wrong video or none at all.
Archives¶
Get All Archives¶
Get Archive¶
Create Archive (Editor)¶
Request Body:
Update Archive (Editor)¶
Delete Archive (Editor)¶
Scene Classifications¶
Get Distinct Labels¶
Get all unique scene classification labels in the catalog.
Search by Label¶
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 all scene classifications for thumbnails in a video.
Properties (Metadata)¶
Extended properties are described by a registry. Each registry row has a property
class, an aspect that holds the property name, and a value. The classes are:
property (class) |
aspect |
value |
|---|---|---|
video_property |
the property name | edit for a text field, or combo={a,b,c} for a dropdown |
thumbnail_property |
the property name | same as above, for scene (thumbnail) properties |
category |
the property name | a grouping label shown in the client, e.g. video, audio, xmp |
namespace |
the property name | the XMP namespace URI, for properties imported from XMP |
A property must have a video_property (or thumbnail_property) row to appear in the
client's search filter, column picker and property editor. category and namespace
rows are optional annotations, keyed by the property name.
Get Property Metadata¶
Get all registry rows for one class. {property} is the class, e.g.
GET /api/v1/properties/meta/video_property lists every defined video property name.
Set Property Metadata (Editor)¶
Register a property. To define a custom video property called MyCustomField:
Request Body:
Use "value": "combo={red,green,blue}" for a dropdown. Set values on individual videos
with PUT /api/v1/videos/{id}/properties.
Delete Property Metadata (Editor)¶
Remove a property definition. For the video_property and thumbnail_property classes
this also deletes the stored values of that property from every video or scene, and,
when the last definition of the name goes, its category and namespace rows. To
delete the MyCustomField property defined above:
Request Body:
Statistics¶
Get Combined Stats¶
Get combined catalog statistics.
Response:
{
"success": true,
"data": {
"videoCount": 1500,
"actorCount": 250,
"imageCount": 5000,
"thumbnailCount": 0
}
}
Get Video Count¶
Get Actor Count¶
Get Image Count¶
Get Thumbnail Count¶
Uploads¶
Upload Video (Editor)¶
Upload a video file using multipart/form-data.
Request:
- Content-Type: multipart/form-data
- Field: file - The video file
Response:
Complete Video Upload (Editor)¶
Finalize upload and add video to catalog.
Request Body:
Cancel Upload (Editor)¶
Cancel upload and delete temporary files.
Upload Image (Editor)¶
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¶
Error Response¶
Simple Result Response¶
For operations that don't return data:
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 |