# Boosted Content API Boosted content allows promoting specific movies or series to the top of listing results when tied to a homepage row. ## How it works - Each homepage row has an `id` (encoded string). - Admin creates a **boosted content** record linking a content item (movie/series) to a homepage row, with a `priority` and optional `boostedUntil` expiration. - When the client fetches `/movies` or `/series` and passes `homepageRowId`, boosted items appear first, ordered by priority (highest first), then by creation date. - Without `homepageRowId`, the endpoints behave as before (ordered by creation date). - Expired boosts (`boostedUntil` in the past) are automatically excluded from results and cleaned up by a background job every 5 minutes. ## Client endpoints ### Movies ``` GET /client/v1/contents/movies?page=1&pageSize=20&homepageRowId={rowId} GET /tv/v1/contents/movies?page=1&pageSize=20&homepageRowId={rowId} GET /mobile/v1/contents/movies?page=1&pageSize=20&homepageRowId={rowId} ``` ### Series ``` GET /client/v1/contents/series?page=1&pageSize=20&homepageRowId={rowId} GET /tv/v1/contents/series?page=1&pageSize=20&homepageRowId={rowId} GET /mobile/v1/contents/series?page=1&pageSize=20&homepageRowId={rowId} ``` **Query parameters:** | Parameter | Type | Required | Description | |----------------|--------|----------|--------------------------------------------------------------------| | page | int | yes | Page number | | pageSize | int | yes | Items per page | | channelId | string | no | Filter by channel | | categoryId | string | no | Filter by category | | homepageRowId | string | no | Homepage row ID. When provided, boosted items appear first. | **Response:** Standard paginated response (`Pagination` / `Pagination`). The response shape does not change - boosted items are simply reordered to the top. ### Getting homepage rows To get the available homepage rows (and their IDs): ``` GET /client/v1/homepage/rows ``` Each row includes `id`, `rowType`, `title`, etc. Use the row `id` as the `homepageRowId` parameter. ## Admin endpoints ### Boosted Contents CRUD Base path: `/admin/v1/boosted-contents` All admin endpoints require `AdminAuthorizationFilter`. #### Create ``` POST /admin/v1/boosted-contents ``` ```json { "contentId": "encoded_content_id", "homepageRowId": "encoded_row_id", "priority": 10, "boostedUntil": "2026-05-01T00:00:00Z" } ``` | Field | Type | Required | Description | |---------------|----------|----------|------------------------------------------------------------------| | contentId | string | yes | Encoded ID of the movie or series | | homepageRowId | string | yes | Encoded ID of the homepage row | | priority | int | yes | Higher value = higher position. Items with same priority fall back to creation date. | | boostedUntil | datetime | no | ISO 8601 UTC. If null, boost never expires. | **Response:** `AdminBoostedContentDto` ```json { "id": "encoded_boosted_content_id", "contentId": "encoded_content_id", "contentTitle": "Movie Title", "homepageRowId": "encoded_row_id", "priority": 10, "boostedUntil": "2026-05-01T00:00:00Z", "createdAt": "2026-04-03T12:00:00Z", "updatedAt": "2026-04-03T12:00:00Z", "createdBy": null, "updatedBy": null } ``` #### List ``` GET /admin/v1/boosted-contents?homepageRowId={encoded_row_id} ``` Returns all boosted contents, optionally filtered by homepage row. Ordered by priority descending. #### Update ``` PUT /admin/v1/boosted-contents/{id} ``` ```json { "contentId": "encoded_content_id", "homepageRowId": "encoded_row_id", "priority": 20, "boostedUntil": "2026-06-01T00:00:00Z" } ``` #### Delete ``` DELETE /admin/v1/boosted-contents/{id} ``` Returns `true` if deleted, `false` if not found. ### Boosted Videos CRUD Same pattern, base path: `/admin/v1/boosted-videos` Uses `videoId` instead of `contentId`. Applies to video listing endpoints (`/videos/all`, `/videos/vod`, `/videos/live`). ## Constraints - A content item can only be boosted once per homepage row (unique constraint on `contentId + homepageRowId`). Attempting to boost the same content in the same row again will return a 400 error. - Deleting a content item or homepage row cascades to its boosted records. ## Ordering logic When `homepageRowId` is provided, results are ordered: 1. Boosted items first (active boost: `boostedUntil` is null or in the future) 2. Among boosted items: by `priority` descending 3. Then all remaining items: by `createdAt` descending