Skip to main content

Get Like Status

Returns the current user’s like status for a specific video.

Parameters

videoId
string
required
The video ID to check like status for

Request

curl http://localhost:3001/api/videos/EFTA01683563/like

Response

userLike
boolean | null
Current user’s like status for this video:
  • true - User has liked this video
  • null - User has not liked this video

Example Responses

Video is liked:
{
  "userLike": true
}
Video is not liked:
{
  "userLike": null
}

Notes

This endpoint automatically identifies the user by their IP address. No authentication headers are required.

Like Video

Like or unlike a video. Requires reCAPTCHA verification. Liking a video you’ve already liked will unlike it (toggle behavior).

Parameters

videoId
string
required
The video ID to like/unlike

Headers

X-Recaptcha-Token
string
required
reCAPTCHA token for verification (skipped in local dev without RECAPTCHA_SECRET_KEY)

Request

curl -X POST http://localhost:3001/api/videos/EFTA01683563/like \
  -H "X-Recaptcha-Token: your-token"

Response

userLike
boolean | null
New like status for this video:
  • true - Video was liked (created like, incremented counter)
  • null - Video was unliked (removed like, decremented counter)

Example Responses

Liking a video:
{
  "userLike": true
}
Unliking a video:
{
  "userLike": null
}

Behavior

Toggle Behavior:
  • If user has not liked the video → Creates like and increments videos.likes by 1
  • If user has already liked the video → Removes like and decrements videos.likes by 1 (floor at 0)
There is no separate “unlike” endpoint. POST to like again to toggle it off.

Side Effects

This endpoint updates the denormalized likes counter in the videos table:
-- When liking
UPDATE videos SET likes = likes + 1 WHERE id = :videoId

-- When unliking
UPDATE videos SET likes = GREATEST(likes - 1, 0) WHERE id = :videoId
The like counter is floored at 0 to prevent negative values in edge cases.

Error Responses

403
Forbidden
reCAPTCHA verification failed:
  • {"error": "Invalid request"} - Missing token
  • {"error": "reCAPTCHA verification failed"} - Token invalid or score < 0.5
500
Internal Server Error
Server error:
  • {"error": "reCAPTCHA verification error"} - Error communicating with reCAPTCHA service

Database Schema

Video Likes Table

Each like is stored as a record with a unique constraint:
id
uuid
Primary key (auto-generated)
videoId
string
Reference to videos.id (cascade delete)
userId
uuid
Reference to users.id (cascade delete)
isLike
boolean
Always true for video likes (boolean field exists for future dislike support)
createdAt
timestamp
When the like was created

Unique Constraint

Constraint: video_user_unique on (videoId, userId)A user can only have one like record per video. This is enforced at the database level.

Notes

Currently, only “likes” are supported. There is no dislike functionality despite the isLike boolean field in the schema (which may be used for future dislikes).
The /api/videos endpoint returns the current likes count for each video. This count is kept in sync by the like/unlike operations.

Build docs developers (and LLMs) love