How Recommendations Work

Learn how Brightcove Recommendations generates recommendations, including the request lifecycle, algorithms, deduplication, and the Recommendations API.

Request Lifecycle

The following steps describe what happens during a playback session with Brightcove Recommendations enabled:

  1. Video starts playback — The player requests recommendations from the Recommendations service. A regular video_view event is tracked.
  2. Recommendations are displayed — The recommendation slate appears (based on the timing configuration). A recommendation_impression event is tracked for each recommended video shown in the slate, so a slate that displays multiple videos counts multiple impressions. The initial video is registered as watched.
  3. Countdown begins — If autoplay is enabled, the countdown timer starts. The next recommended video is pre-fetched.
  4. Recommended video plays — A new video_view is tracked with source_video_id set to the initial video's ID. The player requests the next set of recommendations based on the initial video (not the current one). Previously watched videos are filtered out.
  5. Cycle continues — Steps 2–4 repeat for each subsequent recommendation. All requests remain anchored to the initial video.

Algorithms

Brightcove Recommendations offers three recommendation strategies. Each uses a different primary signal but all apply the same eligibility and restriction rules.

Finds semantically similar content using AI-based similarity as the primary ranking signal. The system analyzes your video metadata to identify the most closely related content in your catalog.

Two boosters refine the results:

  • Tag similarity — Favors videos with overlapping tags, improving precision when metadata is well-structured.
  • Recency booster — Slightly favors newer content so that fresh videos surface alongside evergreen matches.

Identifies viral and popular content by combining multiple signals:

  • Popularity score — Based on total video views within the configured timeframe (daily or weekly).
  • Momentum score — Measures the acceleration of video views, identifying content that is gaining traction quickly.
  • Time decay — Favors recently trending content over older spikes.

After calculating trending scores, the results are rescored by semantic similarity to the initial video and tag matching to maintain relevance.

Recently Added

Surfaces the latest published content by sorting videos by their publication date (newest first). The results are then rescored by semantic similarity to the initial video and tag matching so that the most relevant new content ranks higher.

Deduplication

The player automatically tracks which videos have already been shown during a session and filters them from future recommendations. The source video is also excluded from its own recommendations.

If the player state is reset (e.g., a page refresh), the tracking resets and previously shown videos may appear again.

Fallback Strategy

When the Expand Recommendations setting is enabled in the Admin module and no results are found:

  1. The system retries the query without the look-back period and duration constraints.
  2. Restrictions remain enforced during fallback — they are never relaxed.

This ensures that recommendation slates are not empty while still respecting editorial guardrails.

Recommendations API

In addition to the player plugin, you can access recommendations programmatically via the Recommendations API to power custom UX elements such as rails, carousels, and discovery pages.

Base URL

https://recommendations.api.brightcove.com

Authentication

The Recommendations API uses Brightcove OAuth. Include a Bearer token in the Authorization header. The required permissions depend on the endpoint:

Authorization: Bearer {access_token}
Required OAuth permissions
Endpoint Permission
GET /settings video-cloud/setting/read
POST /settings video-cloud/setting/write
POST /recommendations Any valid Brightcove OAuth token. No specific permission is required.

See Managing API Authentication Credentials for details on obtaining OAuth credentials.

Path Parameters

Common path parameters
Parameter Type Required Description
account_id string Yes Your Video Cloud account ID.

GET /v1/accounts/{account_id}/settings

Returns the recommendation settings for the specified account. If no settings exist, the API creates and returns default settings.

Response

Returns an AccountRecommendationSettings object. See the Settings Model section below for full field reference.

Example

GET /v1/accounts/1234567890/settings
Authorization: Bearer {access_token}
Sample Response
{
  "account_id": "1234567890",
  "timeframe_days": 365,
  "max_video_duration": 1800,
  "min_video_duration": 0,
  "excluded_tags": [],
  "lock_offs": [],
  "campaigns": [],
  "trending_recurrence": "daily",
  "fallback_content": true
}

POST /v1/accounts/{account_id}/settings

Creates or updates the recommendation settings for the specified account. The request body must match the account_id in the path.

Request Body

The body is an AccountRecommendationSettings object. See the Settings Model section below for full field reference. You can pass only the fields you want to update.

Response

Returns the updated AccountRecommendationSettings object.

Errors

Error responses
Status Description
422 The account_id in the request body does not match the path parameter, or validation failed.
500 Failed to save settings.

Example

POST /v1/accounts/1234567890/settings
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "account_id": "1234567890",
  "timeframe_days": 180,
  "max_video_duration": 3600,
  "min_video_duration": 30,
  "excluded_tags": ["internal", "draft"],
  "trending_recurrence": "weekly",
  "fallback_content": true
}

POST /v1/accounts/{account_id}/recommendations

Returns video recommendations for the specified source video. Use this endpoint to power custom recommendation UI elements outside the Brightcove Player.

Request Body

Recommendation request fields
Field Type Required Default Description
video_id string Yes The source video ID (currently playing or anchor video).
excluded_ids array of strings No null List of video IDs to exclude from results (for deduplication).
limit integer No 1 Maximum number of recommendations to return. Range: 1–50.
mode string No related Recommendation strategy: related, trending, or recent.
enable_featured_content boolean No true Whether to include promoted content campaigns in the results.

Response

Returns a RecommendationsResponse object:

Recommendation response fields
Field Type Description
recommendations array List of recommended videos. Each item contains video_id (string) and reason (string: related, trending, recent, or featured).
count integer Number of recommendations returned.

Example

POST /v1/accounts/1234567890/recommendations
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "video_id": "6345678901234",
  "limit": 6,
  "mode": "related",
  "excluded_ids": ["6345678901111", "6345678901222"],
  "enable_featured_content": true
}
Sample Response
{
  "recommendations": [
    {
      "video_id": "6345678901235",
      "reason": "related"
    },
    {
      "video_id": "6345678901236",
      "reason": "related"
    },
    {
      "video_id": "6345678901237",
      "reason": "featured"
    }
  ],
  "count": 3
}

Settings Model

The following tables describe every field in the AccountRecommendationSettings model, used by both the GET and POST settings endpoints.

Core Settings

Core account settings
Field Type Default Description
account_id string Your Video Cloud account ID.
timeframe_days integer 365 Only videos published within this many days are eligible. Range: 1–730.
max_video_duration integer | null 1800 Maximum video duration in seconds. Set to null or 0 for no limit.
min_video_duration integer | null 0 Minimum video duration in seconds. Set to null or 0 for no limit. Cannot exceed max_video_duration.
excluded_tags array of strings | null null Videos with any of these tags are excluded from all recommendation results.
trending_recurrence string daily Time window for trending scoring: daily or weekly.
fallback_content boolean false When true, falls back to a relaxed query (no timeframe or duration limits) if eligible results are too few. Restrictions remain enforced.

Lock-offs

Lock-offs are editorial constraints that narrow recommendations. A lock-off bundles one or more constraints that are combined with AND logic. A constraint only applies if the source video also has the matching value(s) (intersection logic).

Lock-off fields
Field Type Default Description
lock_off_id string Unique lock-off identifier.
name string Human-readable name for the lock-off.
description string | null null Optional description.
status string active active or archived. Only active lock-offs within their date range are applied.
start_date datetime | null null ISO 8601. Lock-off is active from this date onward.
end_date datetime | null null ISO 8601. Must be after start_date.
constraints array At least one constraint required. All constraints in a single lock-off must share the same type.

Lock-off Constraints

Constraint fields
Field Type Description
type string Constraint type: tag or custom_field.
field_name string | null Required when type is custom_field. The custom field name to match against.
value string The tag name or custom field value that recommended videos must match.

Featured Content Campaigns

Campaigns insert promoted videos into the recommendation carousel before organic results. Campaign videos are assigned reason: "featured".

Campaign fields
Field Type Default Description
campaign_id string Unique campaign identifier.
status string active active or archived. Only active campaigns within their date range are included.
video_id string The video ID to feature in recommendations.
frequency_percentage decimal Probability the campaign appears in a request (when no carousel_position is set). Range: 0.0–100.0.
view_goal integer | null null Target impression count. The campaign is skipped once this goal is reached.
start_date datetime ISO 8601. Campaign becomes active from this date.
end_date datetime ISO 8601. Must be after start_date.
carousel_position integer | null null 0-indexed position in the carousel. When set, the campaign appears at this exact slot instead of using random frequency.

Validation Rules

  • timeframe_days must be between 1 and 730.
  • min_video_duration cannot exceed max_video_duration.
  • All constraints within a single lock-off must share the same type (all tag or all custom_field).
  • end_date must be after start_date for both lock-offs and campaigns.
  • frequency_percentage must be between 0.0 and 100.0.
  • Each lock-off must have at least one constraint.