Hi Creators,
At RDC, we shared our vision for Roblox Moments, a complete ecosystem for user content that transforms how players create, share, and discover experiences. We’re committed to giving you the same tools we used to build the Moments experience itself.
Today, we’re taking the next major step forward by introducing the Upload API (part of CaptureService), the Recommendations API, and the Moments Experience Source Code. This suite of tools is designed to help you build your own in-experience creation and discovery features, driving engagement, retention, and new player growth.
You’ve already started using our foundational APIs (Video Captures API and Share Link API) to capture those epic moments. Now, these new additions close the loop, turning captures into a dynamic, social content reel inside your game. Here’s a breakdown of our full Moments toolkit:
| Creator Tool | What It Does for Your Game | How You Can Use It |
|---|---|---|
| Video Captures API | Programmatically trigger and capture peak gameplay moments. | Automatically record a player’s game-winning goal or a perfect speedrun finish. |
| Share Link API | Create custom deep links to drive targeted re-engagement. | Send players directly back to the specific obby level they saw in a shared Moment. |
| [NEW] Upload API (Beta) | Allow users to publish user captured content directly within your experience. | After a great fashion show, prompt the user to publish their runway content to your in-game gallery. |
| [NEW] Recommendations API (Beta) | Configure your own recommendation algorithm to highlight relevant content for players right inside your experience. Track its performance in Creator Hub under Recommendation Service. | Power your own in-game billboard with a “Highlight Reel” showing the most engaging content from the players in your experience. |
| [NEW] Moments Source Code | Provides a reference for how you can integrate custom, content-based player experiences inside your game. | Get a concrete example to inform how you can build and customize your own in-experience content publishing and consumption flow. |
New Creator Tools: Closing the Content Sharing Loop
Upload API (Beta)
This API enables users to publish and share their captured content within your experience. No more relying on players leaving the platform to share, the entire creation-to-sharing loop stays in your game, driving more traffic and focus back to your experience.
During Beta, this API will only let players upload captures recorded in your experience. In the future, we will expand the API to support uploads of captures recorded in other experiences.
Click here to view the code snippet
--[[
Upload API Overview
The Upload API describes a set of functions added to CaptureService that allow the retrieval and upload of a user's captures.
Key Features:
- Request permissions to view and upload a user's captures
- Fetch captures from gallery
- Upload capture to the asset system
At the moment, only captures taken in the current experience can be retrieved and uploaded.
]]
local CaptureService = game:GetService("CaptureService")
-- ============================================================================
-- STEP 1: Request permission
-- ============================================================================
local accepted = CaptureService:PromptCaptureGalleryPermissionAsync(Enum.CaptureGalleryPermission.ReadAndUpload)
-- ============================================================================
-- STEP 2: Fetch captures from gallery
-- ============================================================================
local allCaptures = {}
if accepted then
local capturesPages
local success, result = pcall(function()
local readResult, pages = CaptureService:ReadCapturesFromGalleryAsync()
if readResult == Enum.ReadCapturesFromGalleryResult.Success then
capturesPages = pages
end
return readResult
end)
if not success or result ~= Enum.ReadCapturesFromGalleryResult.Success then
warn("Failed to fetch initial captures: " .. result)
return
end
-- Iterate through current page
local currentPage = capturesPages:GetCurrentPage()
for _, capture in currentPage do
table.insert(allCaptures, capture)
end
-- Advance to next page until finished
while not capturesPages.IsFinished do
local advanceToNextPageSuccess, _ = pcall(function()
capturesPages:AdvanceToNextPageAsync()
end)
if not advanceToNextPageSuccess then
return
end
currentPage = capturesPages:GetCurrentPage()
for _, capture in currentPage do
table.insert(allCaptures, capture)
end
end
end
-- ============================================================================
-- STEP 3: Upload a capture
-- ============================================================================
-- Here, we'd likely want to show the user's captures to them and prompt them to upload one, but for the example, we can take the first capture in the list.
if #allCaptures > 0 then
local capture = allCaptures[1]
local success, result = pcall(function()
-- This step may take a few minutes
local uploadCaptureResult, assetId = CaptureService:UploadCaptureAsync(capture)
if uploadCaptureResult ~= Enum.UploadCaptureResult.Success then
-- Handle failure
return nil
end
return assetId
end)
if not success then
-- Handle error
end
-- Now we can use the returned asset in-experience
end
Example Use Case: A competitive game uses the Upload API to allow players to instantly submit their “Play of the Game” video to an in-game leaderboard or community feed after a match ends.
Recommendations API (Beta)
This is the engine for in-experience discovery. Built from similar tech behind Roblox’s Home Discovery, integrate your own content recommendations right into your experience. Use this API to rank any content within your experience, giving you full control over how it’s displayed to maximize player engagement and retention. Once set up, track and optimize performance within Creator Hub under Recommendation Service!
Click here to view the code snippet
--[[
RecommendationService API Overview
RecommendationService is a content-agnostic service that helps you create personalized recommendation
systems for your Roblox experience. It handles the complex logic of ranking and ordering content
based on user behavior, while you focus on defining what content to recommend.
Key Features:
- Register items to be recommended (games, assets, experiences, etc.)
- Generate personalized recommendation lists for users
- Log user interactions to improve recommendation quality over time
Typical Workflow:
1. Register items that you want to recommend to users
2. Generate recommendation lists when users need them
3. Log user interactions (views, clicks, reactions) as they happen
4. Repeat steps 2-3 to continuously improve recommendations
This service is flexible and can be used for various recommendation scenarios.
]]
local RecommendationService = game:GetService("RecommendationService")
local replicatedStorage = game:GetService("ReplicatedStorage")
-- ============================================================================
-- STEP 1: REGISTER ITEMS
-- ============================================================================
-- Before you can recommend items, you need to register them with the service.
-- You'll need a RemoteFunction to allow clients to request item registration.
-- Assume a RemoteFunction named 'RegisterItemRemote' exists in ReplicatedStorage
local registerItemRemote = replicatedStorage.RegisterItemRemote
registerItemRemote.OnServerInvoke = function(player, refId)
-- Create a registration request with item details
local request: RegisterRecommendationItemRequest = {
-- ContentType gives a hint on the content:
-- - Dynamic: Videos
-- - Static: Images
-- - Interactive: Games, 3D models, etc.
ContentType = Enum.RecommendationItemContentType.Dynamic,
-- ReferenceId is your unique identifier for this item.
-- This links the recommendation system to your own data storage.
-- Store additional metadata in your DataStore; RecommendationService only
-- stores recommendation-related data.
ReferenceId = refId,
-- Duration in seconds. How long is this content.
Duration = 60,
-- Visibility controls who can see this item:
-- - Public: Visible to all users
-- - Private: Only visible to the creator.
Visibility = Enum.RecommendationItemVisibility.Public,
-- CustomTags help categorize and filter items (e.g., language, season, genre)
-- These can be used to boost certain items in recommendations
CustomTags = {"locale:en-us", "seasonal:summer"},
}
-- Register the item with error handling
local success, response = pcall(function()
return RecommendationService:RegisterItemAsync(player, request)
end)
if success and response then
print("Successfully registered item. ItemId: " .. response.ItemId)
-- The service returns an ItemId that you'll use for future operations
return response.ItemId
else
warn("Failed to register item. Error: " .. tostring(response))
return nil
end
end
-- ============================================================================
-- STEP 2: GENERATE RECOMMENDATION LISTS
-- ============================================================================
-- Once items are registered, you can generate personalized recommendation lists.
-- This can be called from either client or server scripts, depending on your needs.
-- Define the request parameters for generating recommendations
local request: GenerateRecommendationItemListRequest = {
-- ConfigName: The recommendation strategy/algorithm to use
ConfigName = "MaximizeEngagement",
-- LocationId: Where in your experience these recommendations will be shown.
-- It will not affect the recommendation results, but their performance metrics will be shown separately in the Creator Hub.
LocationId = "Lobby",
-- PageSize: Number of items to return per page.
PageSize = 10
}
-- Generate the recommendation list (returns a paginated result)
local success, recommendationPages = pcall(function()
return RecommendationService:GenerateItemListAsync(request)
end)
if success then
-- Get the first page of recommended items
local currentPage = recommendationPages:GetCurrentPage()
-- Iterate through the recommended items
for _, item in ipairs(currentPage) do
print("ItemId: " .. item.ItemId) -- Service-generated unique ID
print(" ReferenceId: " .. item.ReferenceId) -- Your original identifier
print(" TracingId: " .. item.TracingId) -- Use this when logging interactions
-- Use the ReferenceId to look up full item details from your DataStore
-- Use the TracingId when logging user interactions (see Step 3)
end
-- To get more items, you can call:
-- recommendationPages:AdvanceToNextPageAsync()
-- local nextPage = recommendationPages:GetCurrentPage()
else
warn("Failed to generate recommendations: " .. tostring(recommendationPages))
end
-- ============================================================================
-- STEP 3: LOG USER INTERACTIONS
-- ============================================================================
-- Logging user interactions helps the recommendation system learn what users like
-- and improves future recommendations. This should be done from a client script
-- when users interact with recommended items.
-- Log when a user views a recommended item (impression event)
local impressionDetail: RecommendationImpressionEventDetails = {
-- Duration: How long the user viewed the item (in seconds)
Duration = 5,
-- ItemPosition: Where the item appeared in the list (1 = first item, 2 = second, etc.)
-- Helps the system understand which positions get more attention
ItemPosition = 1,
-- DepartureIntent: How the user left the item
-- - Positive: User engaged positively (e.g., clicked, liked)
-- - Neutral: User scrolled past
-- - Negative: User dismissed or skipped
DepartureIntent = Enum.RecommendationDepartureIntent.Neutral
}
-- Log the view event
-- Parameters: event type, itemId from recommendation, tracingId from recommendation, details
RecommendationService:LogImpressionEvent(
Enum.RecommendationImpressionType.View,
"itemId", -- Use item.ItemId from the recommendation list
"tracingId", -- Use item.TracingId from the recommendation list
impressionDetail
)
-- Log when a user takes an action on a recommended item (action event)
local actionDetail: RecommendationActionEventDetails = {
-- ReactionType: Type of action taken (e.g., "Like", "Thumb up")
-- This is a string you define based on your experience's actions
ReactionType = "Like"
}
-- Log the action event
-- Parameters: action type, itemId, tracingId, details
RecommendationService:LogActionEvent(
Enum.RecommendationActionType.AddReaction,
"itemId", -- Use item.ItemId from the recommendation list
"tracingId", -- Use item.TracingId from the recommendation list
actionDetail
)
-- The more data you log, the better your recommendations will become over time
Example Use Case: A car racing experience uses the Recommendations API to display the fastest laps and coolest overtakes as a dynamic highlight reel on jumbotrons around the track, inspiring others to try and beat the record.
Moments Experience Source Code
We’re giving you the full Moments source code. To access the source code, go to the Roblox Moments experience and click the three dot menu > “Edit in Studio”. This provides a reference for the entire Moments workflow – capture, editing, and publishing. This gives you a concrete example on how to create a content sharing feature that matches your own experience’s style and needs.
Example Use Case: For a fashion experience, you can reference how the Moments experience empowers players to creatively edit their captures, and integrate relevant editing functionality into your own experience, making self-expression a core part of how your players publish their unique looks.
Technical Details & Get Started
All of these APIs and the Source Code are available now!
Foundation APIs:
Here is comprehensive documentation and availability updates for the Upload API, Recommendations API, and the Moments Source Code.
Amplify Your Experience and Drive Discovery
We’ve given you the tools; now we invite you to push the boundaries of creativity. We are already actively exploring how user-generated content can further enrich the platform, and you can expect future updates that will expand what’s possible with the Moments ecosystem.
We can’t wait to see the creative ways you innovate with these tools. Share your feedback and ideas below!
Thank you,
@corepcgamer, Moments Product Lead, Roblox User Team
FAQs
Will voice ever be available to record in Moments?
- Currently, shared Moments videos include some in-experience audio (sound effects, music) but do not record voice communication for safety and privacy reasons. We continuously evaluate our platform capabilities and will share updates here if any changes to audio recording policies are planned for the future.
As a creator, can I control what content is recommended through the Recommendations API?
- Yes. The power of the Recommendations API is in the control it gives you. You can select how content is ranked, fully customize its display, and eventually personalize for your individual players within your experience. For more details on how to implement this, check out our documentation.
As a creator, will I be penalized/moderated for content surfaced through the Recommendations API?
- No, you will not be penalized for content that is surfaced through a reel you build using the Recommendations API. All captured and published content, whether shared in the main Moments experience or through your custom in-experience systems, is subject to proactive moderation before publication to ensure it complies with Community Standards.
Will my experience be restricted to 13+ when implementing Upload API?
- At this time, your experience’s content maturity label will not be impacted. In the future, we’ll add cross-experience upload support. If you call the Upload API for users to upload media from other experiences, then you must answer “yes” to “Cross-Experience Content”, and the experience will receive a ‘Moderate’ content maturity label and be age-gated to 13+.



