Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/barcode8/VideoHub/llms.txt

Use this file to discover all available pages before exploring further.

Once a video is on the platform, VideoHub provides endpoints to fetch its full details — including like counts and ownership info — update its metadata, remove it entirely from both the database and Cloudinary, or flip its visibility between published and hidden. All write operations require authentication. The toggle endpoint enforces ownership; the update and delete endpoints authenticate the caller but do not verify ownership in the controller.

GET /api/v1/videos/:videoId

Fetches a single video document enriched with owner details, total like count, and — when a valid JWT is present — whether the requesting user has liked the video. Authentication: Optional (verifyJWTIfAvailable)

Path Parameters

videoId
string
required
The MongoDB ObjectId of the video to retrieve.

Errors

StatusCause
400videoId parameter is missing
400videoId is not a valid MongoDB ObjectId format
404No video found with the given ID

Response

The likes array used internally for aggregation is removed from the final response via $project: { likes: 0 }. Only the computed fields below are returned.
_id
string
The unique MongoDB ObjectId of the video.
title
string
The display title of the video.
description
string
The video description.
videoFile
string
Cloudinary URL pointing to the video file. Will read "processing" while the background upload is still in progress.
thumbnail
string
Cloudinary URL pointing to the thumbnail image. Will read "processing" while the background upload is still in progress.
duration
number
Video length in seconds as reported by Cloudinary. Reads 0 while processing.
views
number
Total view count.
isPublished
boolean
Whether the video is publicly visible.
ownerDetails
object
Embedded owner information resolved from the users collection via $lookup.
likesCount
number
Total number of likes the video has received, computed via $lookup against the likes collection.
isLiked
boolean
true if the authenticated requester’s _id is found in the likedBy field of the likes documents for this video; false if they have not liked it or if the request was unauthenticated.
createdAt
string
ISO 8601 timestamp of when the document was created.
updatedAt
string
ISO 8601 timestamp of the most recent document update.

Example

curl -X GET "https://api.videohub.example/api/v1/videos/6657f3c2a4e1b2c3d4e5f601" \
  -H "Authorization: Bearer <your_jwt_token>"
{
  "statusCode": 200,
  "data": {
    "_id": "6657f3c2a4e1b2c3d4e5f601",
    "title": "My First Vlog",
    "description": "A quick trip through the city.",
    "videoFile": "https://res.cloudinary.com/demo/video/upload/v1/myvideo.mp4",
    "thumbnail": "https://res.cloudinary.com/demo/image/upload/v1/mythumb.jpg",
    "duration": 312.5,
    "views": 1024,
    "isPublished": true,
    "ownerDetails": {
      "_id": "6657f3c2a4e1b2c3d4e5f600",
      "username": "alexvlogs",
      "fullName": "Alex Johnson",
      "avatar": "https://res.cloudinary.com/demo/image/upload/v1/avatar.jpg"
    },
    "likesCount": 87,
    "isLiked": true,
    "createdAt": "2025-01-15T10:30:00.000Z",
    "updatedAt": "2025-01-15T10:32:45.000Z"
  },
  "message": "Video fetched successfully"
}

PATCH /api/v1/videos/:videoId

Updates one or more metadata fields on an existing video. All body fields are optional, but at least one must be supplied. When a new thumbnail is provided, the old one is automatically removed from Cloudinary before the new URL is saved. Authentication: Required (verifyJwt)
The controller authenticates the caller but does not verify that they are the video’s owner. Any authenticated user who knows the videoId can update the video’s metadata. Ownership enforcement is only applied by the toggle-publish endpoint.
Only title, description, and thumbnail can be changed via this endpoint. To change the actual video file you must delete the video and re-upload it using the two-step publish flow.

Path Parameters

videoId
string
required
The MongoDB ObjectId of the video to update.

Request Body (multipart/form-data)

title
string
Replacement title for the video. Ignored if empty or whitespace-only.
description
string
Replacement description for the video. Ignored if empty or whitespace-only.
thumbnail
file
A new thumbnail image. When provided, the existing thumbnail’s public ID is extracted from its Cloudinary URL and destroyed via cloudinary.uploader.destroy before the new one is uploaded and saved.

Errors

StatusCause
400videoId is not a valid ObjectId format, or no valid update fields were provided
404No video found with the given ID
500Thumbnail upload to Cloudinary failed

Response

Returns the full updated video document (post-update snapshot from MongoDB).
{
  "statusCode": 200,
  "data": {
    "_id": "6657f3c2a4e1b2c3d4e5f601",
    "title": "My First Vlog — Director's Cut",
    "description": "An extended trip through the city with bonus footage.",
    "videoFile": "https://res.cloudinary.com/demo/video/upload/v1/myvideo.mp4",
    "thumbnail": "https://res.cloudinary.com/demo/image/upload/v1/newthumb.jpg",
    "duration": 312.5,
    "views": 1024,
    "isPublished": true,
    "owner": "6657f3c2a4e1b2c3d4e5f600",
    "createdAt": "2025-01-15T10:30:00.000Z",
    "updatedAt": "2025-01-15T11:05:22.000Z"
  },
  "message": "Video details changed successfully"
}

Example

# Update the title and swap in a new thumbnail
curl -X PATCH "https://api.videohub.example/api/v1/videos/6657f3c2a4e1b2c3d4e5f601" \
  -H "Authorization: Bearer <your_jwt_token>" \
  -F "title=My First Vlog — Director's Cut" \
  -F "description=An extended trip through the city with bonus footage." \
  -F "thumbnail=@/path/to/new-cover.jpg"

DELETE /api/v1/videos/:videoId

Permanently removes a video from the platform. Both the video file and thumbnail are destroyed on Cloudinary before the MongoDB document is deleted. Authentication: Required (verifyJwt)
This action is irreversible. The video file, thumbnail, and all associated database records are permanently removed. Cloudinary deletion is attempted synchronously — if it fails, a 500 error is returned and the database record is not deleted, preserving consistency.
The controller does not verify that the caller is the video’s owner before deleting. Any authenticated user who knows the videoId can delete the video.

Path Parameters

videoId
string
required
The MongoDB ObjectId of the video to delete.

Errors

StatusCause
400videoId is not a valid MongoDB ObjectId format
404No video found with the given ID
500Cloudinary deletion failed; the database record is preserved

Response

Returns the video document as it existed just before deletion.
{
  "statusCode": 200,
  "data": {
    "_id": "6657f3c2a4e1b2c3d4e5f601",
    "title": "My First Vlog",
    "description": "A quick trip through the city.",
    "videoFile": "https://res.cloudinary.com/demo/video/upload/v1/myvideo.mp4",
    "thumbnail": "https://res.cloudinary.com/demo/image/upload/v1/mythumb.jpg",
    "duration": 312.5,
    "views": 1024,
    "isPublished": true,
    "owner": "6657f3c2a4e1b2c3d4e5f600",
    "createdAt": "2025-01-15T10:30:00.000Z",
    "updatedAt": "2025-01-15T10:32:45.000Z"
  },
  "message": "Video deleted successfully"
}

Example

curl -X DELETE "https://api.videohub.example/api/v1/videos/6657f3c2a4e1b2c3d4e5f601" \
  -H "Authorization: Bearer <your_jwt_token>"

PATCH /api/v1/videos/toggle/publish/:videoId

Flips the isPublished flag on a video between true and false. Only the video’s owner can call this endpoint — ownership is verified in the controller before the toggle is applied. Authentication: Required (verifyJwt)
This endpoint is mounted at /toggle/publish/:videoId, which takes precedence over the generic /:videoId route. Make sure to use the full path as shown.

Path Parameters

videoId
string
required
The MongoDB ObjectId of the video whose publish status should be toggled.

Errors

StatusCause
400videoId parameter is missing or not a valid MongoDB ObjectId format
403The authenticated user is not the owner of the video
404No video found with the given ID

Response

isPublished
boolean
The new publish status after the toggle — true if the video is now public, false if it is now hidden.
The document is saved with validateBeforeSave: false so that the toggle bypasses other schema validations.
{
  "statusCode": 200,
  "data": {
    "isPublished": false
  },
  "message": "Video is now Hidden"
}
{
  "statusCode": 200,
  "data": {
    "isPublished": true
  },
  "message": "Video is now Published"
}

Example

curl -X PATCH "https://api.videohub.example/api/v1/videos/toggle/publish/6657f3c2a4e1b2c3d4e5f601" \
  -H "Authorization: Bearer <your_jwt_token>"

Video Object Schema

The following fields make up the video document stored in MongoDB and returned by all endpoints in this section.
_id
string
Unique MongoDB ObjectId identifying the video. Pre-generated by the POST /api/v1/videos/init endpoint before the database record is created.
title
string
The display title of the video. Required (required: true in schema).
description
string
A text description of the video’s content. Required at the schema level (required: true); can be updated via the PATCH endpoint.
videoFile
string
Cloudinary URL for the video file. Required (required: true in schema). Populated with "processing" while the background upload is running; replaced with the real URL on completion.
thumbnail
string
Cloudinary URL for the thumbnail image. Required (required: true in schema). Populated with "processing" while the background upload is running; replaced with the real URL (or an auto-generated still frame) on completion.
duration
number
Video duration in seconds as reported by Cloudinary. Required (required: true in schema). Set to 0 while processing; updated when the background job finishes. Videos exceeding 3600 seconds (1 hour) are rejected and deleted.
views
number
Total view count. Defaults to 0 on creation.
isPublished
boolean
Controls public visibility. The schema default is true, but publishVideoDraft explicitly sets this to false on creation so the video remains hidden until background processing succeeds. Can be toggled manually by the owner via the toggle endpoint.
owner
string
MongoDB ObjectId referencing the User document of the channel that uploaded the video.
createdAt
string
ISO 8601 timestamp added automatically by Mongoose’s timestamps option.
updatedAt
string
ISO 8601 timestamp updated automatically by Mongoose on every document save.

Build docs developers (and LLMs) love