BloxMetrics SDK
The complete analytics SDK for Roblox games. Track players, revenue, economy, progression, and errors — all with a single require() call.
Installation
Set up BloxMetrics in 4 steps. No files to download, no packages to install.
Enable API access in your game
In Roblox Studio, go to Game Settings → Security → enable "Enable Studio Access to API Services". This is required for the SDK to send data.
Get your API key
Go to your BloxMetrics Dashboard → select your game → Settings → copy the API key.
Create a Script in Roblox Studio
In the Explorer panel, create a new Script inside ServerScriptService. Name it BloxMetrics.
Paste the code and publish
Copy the code below, paste it into the script, replace YOUR_API_KEY with your actual key, and hit Publish. That's it!
Paste this into your script:
local BM = require(127217366828209)
BM:Init("YOUR_API_KEY")
:EnablePlayerTracking() -- sessions, devices, countries (automatic)
:EnableRevenueTracking() -- gamepass purchases (automatic)
:EnableEventTracking() -- custom events
:EnableErrorTracking() -- Lua errors (automatic)
-- ✅ Done! Data will appear in your Dashboard within 60 seconds.ServerScriptService, never in a LocalScript. Your API key is never exposed to players.Quick Start
After pasting the code, hit Play in Roblox Studio. Data will start appearing in your Dashboard within 30–60 seconds.
Enable*() — no extra code needed.API Key
Each game has its own API key. Find yours here:
ServerScriptService scripts. If placed client-side, anyone can write data to your account.Init & Config
BM:Init() must be called before anything else — usually the first line of your script.
| Parameter | Type | Description |
|---|---|---|
apiKey | string | Your API key from the BloxMetrics Dashboard |
optionsoptional | table | Optional settings (e.g. debug mode) |
BM:Init("bm_live_abc123", {
debug = true, -- prints SDK logs to the Output window
})debug = true while testing — you'll see every SDK request in the Output window. Remove it before publishing to production.Player Tracking
Automatically tracks player sessions, devices, countries, and retention. Zero config required.
Auto-tracked data:
Player Properties
Attach custom data to players for segmentation and filtering in the dashboard.
| Parameter | Type | Description |
|---|---|---|
player | Player | The player instance |
key | string | Property name |
value | any | Property value |
amountoptional | number | Increment amount (default: 1) |
-- Set properties on join
Players.PlayerAdded:Connect(function(player)
BM:SetPlayerProperty(player, "level", 1)
BM:SetPlayerProperty(player, "clan", "none")
BM:SetPlayerProperty(player, "vip", false)
end)
-- Increment on events
BM:IncrementPlayerProperty(player, "kills", 1)
BM:IncrementPlayerProperty(player, "coins_earned", 50)
-- Read
local level = BM:GetPlayerProperty(player, "level")Revenue Tracking
Automatically tracks GamePass purchases via MarketplaceService.PromptGamePassPurchaseFinished. For Developer Products, use HandleProcessReceipt.
| Parameter | Type | Description |
|---|---|---|
player | Player | The buyer |
productId | number|table | Product ID or table with fields |
productNameoptional | string | Display name |
robuxAmountoptional | number | Price in Robux |
productTypeoptional | string | "gamepass" | "devproduct" | "subscription" |
-- Manual tracking (if not using HandleProcessReceipt)
BM:TrackPurchase(player, 12345, "VIP Pass", 499, "gamepass")
-- Or pass a table:
BM:TrackPurchase(player, {
productId = 12345,
name = "100 Coins",
robux = 25,
type = "devproduct",
})Process Receipt
Replaces MarketplaceService.ProcessReceipt. Handles receipt validation, purchase tracking, and your reward logic in one place.
BM:HandleProcessReceipt({
-- Product ID → handler
[111111] = {
name = "100 Coins",
handler = function(player)
-- Your reward logic:
PlayerData:AddCoins(player, 100)
BM:TrackSource(player, "Coins", 100, "iap", "100_coins_pack")
return true -- must return true to confirm
end,
},
[222222] = {
name = "VIP Boost",
handler = function(player)
PlayerData:ActivateVIP(player)
return true
end,
},
})Economy Tracking
Track in-game currency flow — sources (earning) and sinks (spending). Monitor inflation, find balancing issues.
| Parameter | Type | Description |
|---|---|---|
player | Player | The player |
currency | string | Currency name (must be in EnableEconomyTracking list) |
amount | number | Amount earned/spent |
itemType | string | Category: "quest", "shop", "iap", "combat", etc. |
itemIdoptional | string | Specific item identifier |
BM:EnableEconomyTracking({ "Coins", "Gems", "Tickets" })
-- Sources (player EARNS currency)
BM:TrackSource(player, "Coins", 100, "quest", "daily_quest_1")
BM:TrackSource(player, "Coins", 50, "combat", "kill_reward")
BM:TrackSource(player, "Gems", 10, "iap", "starter_pack")
-- Sinks (player SPENDS currency)
BM:TrackSink(player, "Coins", 500, "shop", "speed_potion")
BM:TrackSink(player, "Gems", 25, "gacha", "legendary_crate")Progression Tracking
Track level/stage/mission completion, failure rates, and difficulty hotspots. Supports up to 3 hierarchy levels.
| Parameter | Type | Description |
|---|---|---|
player | Player | The player |
p1 | string | Top level: "World1", "Tutorial", "Season2" |
p2optional | string | Mid level: "Stage3", "Chapter1" |
p3optional | string | Bottom level: "Level5", "Boss" |
scoreoptional | number | Score/rating on complete/fail |
-- Simple: tutorial
BM:StartProgression(player, "Tutorial")
BM:CompleteProgression(player, "Tutorial")
-- 2-level: world + stage
BM:StartProgression(player, "Enchanted Forest", "Stage 3")
BM:FailProgression(player, "Enchanted Forest", "Stage 3", nil, 2500)
-- 3-level: world + stage + level
BM:StartProgression(player, "World1", "Zone3", "Boss")
BM:CompleteProgression(player, "World1", "Zone3", "Boss", 9800)Custom Events
| Parameter | Type | Description |
|---|---|---|
player | Player | The player |
eventName | string | Event name (snake_case recommended) |
eventDataoptional | table | Optional key-value metadata |
-- Simple event
BM:TrackEvent(player, "shop_opened")
-- With metadata
BM:TrackEvent(player, "item_purchased", {
item = "Golden Sword",
cost = 500,
currency = "Coins",
})
BM:TrackEvent(player, "boss_defeated", {
boss = "Dragon King",
time = 45.2,
deaths = 3,
})Funnels
Track conversion funnels — onboarding, shop flow, tutorial completion, etc. View drop-off rates in the dashboard.
| Parameter | Type | Description |
|---|---|---|
player | Player | The player |
funnelName | string | Funnel identifier: "onboarding", "shop_flow" |
stepNumber | number | Step number (1, 2, 3...) |
stepName | string | Human-readable step name |
-- Onboarding funnel
BM:TrackFunnelStep(player, "onboarding", 1, "game_opened")
BM:TrackFunnelStep(player, "onboarding", 2, "tutorial_started")
BM:TrackFunnelStep(player, "onboarding", 3, "tutorial_completed")
BM:TrackFunnelStep(player, "onboarding", 4, "first_purchase")
-- Shop flow
BM:TrackFunnelStep(player, "shop_flow", 1, "shop_opened")
BM:TrackFunnelStep(player, "shop_flow", 2, "item_viewed")
BM:TrackFunnelStep(player, "shop_flow", 3, "purchased")Design Events
Hierarchical events for game design analysis. Use colon-separated IDs for grouping.
-- Weapon usage tracking
BM:TrackDesign(player, "Combat:Kill:Sword", 1)
BM:TrackDesign(player, "Combat:Kill:Bow", 1)
-- Map interaction
BM:TrackDesign(player, "Map:Zone:Entered:Forest", 1)
-- Gacha results
BM:TrackDesign(player, "Gacha:Premium:Legendary", 1)Error Tracking
Automatically captures Lua errors with stack traces. You can also manually log errors with severity levels.
| Parameter | Type | Description |
|---|---|---|
player | Player|nil | Associated player (nil for server errors) |
severity | string | "critical" | "error" | "warning" | "info" | "debug" |
message | string | Error message |
BM:EnableErrorTracking() -- auto-captures Lua errors
-- Manual error tracking
local ok, err = pcall(function()
-- risky DataStore operation
DataStore:SetAsync(key, data)
end)
if not ok then
BM:TrackError(player, "critical", "DataStore save failed: " .. tostring(err))
end
-- Warnings
BM:TrackError(player, "warning", "Player inventory near limit: " .. #inventory)
-- Server-wide errors (no player)
BM:TrackError(nil, "error", "Matchmaking service unavailable")auto_captured = true in the dashboard so you can distinguish them from manual reports.Access Control
Tag players with access levels (VIP, premium, beta, admin) for segmentation in analytics.
-- Grant on gamepass ownership
if MarketplaceService:UserOwnsGamePassAsync(player.UserId, VIP_PASS_ID) then
BM:GrantAccess(player, "vip")
end
-- Check
if BM:HasAccess(player, "vip") then
-- give VIP perks
end
-- Revoke
BM:RevokeAccess(player, "beta_tester")
-- Get all levels
local levels = BM:GetAccessLevels(player)
-- → { "vip", "beta_tester" }Identity
Link a player to a custom ID (e.g., your own user system, external database ID).
BM:Identify(player, "user_abc123")Debug & Status
-- Toggle debug logs
BM:SetDebug(true)
-- Check status
print(BM:IsInitialized()) -- true/false
local status = BM:GetStatus()
-- → { initialized = true, queueSize = 5, modules = {...} }
-- Force-send queued events (useful before server shutdown)
BM:Flush()Full Example
A complete integration showing every feature. Copy what you need.
local Players = game:GetService("Players")
local BM = require(127217366828209)
-- ═══ STEP 1: Initialize ═══
BM:Init("YOUR_API_KEY", { debug = true })
:EnablePlayerTracking()
:EnableRevenueTracking()
:EnableEventTracking()
:EnableEconomyTracking({ "Coins", "Gems" })
:EnableProgressionTracking()
:EnableErrorTracking()
-- ═══ STEP 2: Developer Products ═══
BM:HandleProcessReceipt({
[111111] = {
name = "100 Coins",
handler = function(player)
-- your reward logic
BM:TrackSource(player, "Coins", 100, "iap", "100_coins_pack")
return true
end,
},
})
-- ═══ STEP 3: Player Setup ═══
Players.PlayerAdded:Connect(function(player)
BM:SetPlayerProperty(player, "level", 1)
BM:TrackFunnelStep(player, "onboarding", 1, "game_opened")
end)
-- ═══ GAME LOGIC ═══
-- Level complete
local function onLevelComplete(player, world, stage, score)
BM:CompleteProgression(player, world, stage, nil, score)
BM:IncrementPlayerProperty(player, "levels_completed", 1)
local reward = math.floor(score / 10)
BM:TrackSource(player, "Coins", reward, "level_reward", stage)
end
-- Shop purchase
local function onShopPurchase(player, item, cost)
BM:TrackSink(player, "Coins", cost, "shop", item)
BM:TrackEvent(player, "item_purchased", {
item = item, cost = cost,
})
end
-- Safe DataStore save
local function safeSave(player, data)
local ok, err = pcall(function()
DataStore:SetAsync(tostring(player.UserId), data)
end)
if not ok then
BM:TrackError(player, "critical", "Save failed: " .. tostring(err))
end
end
print("[Game] BloxMetrics ready ✅")Client Script(Optional)
For accurate device detection (desktop / mobile / console / VR), add this LocalScript to StarterPlayerScripts. Without it, device data defaults to platform detection.
BloxMetricsRemotes folder is created automatically by the server SDK when you call EnablePlayerTracking(). You don't need to create it manually — just make sure the server script is running before this client script.local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local VRService = game:GetService("VRService")
local remotes = ReplicatedStorage:WaitForChild("BloxMetricsRemotes", 10)
if not remotes then return end
local reportDevice = remotes:WaitForChild("ReportDevice", 5)
if not reportDevice then return end
local function getDevice()
if VRService.VREnabled then return "vr"
elseif UserInputService.TouchEnabled
and not UserInputService.KeyboardEnabled then return "mobile"
elseif UserInputService.GamepadEnabled
and not UserInputService.KeyboardEnabled then return "console"
else return "desktop"
end
end
reportDevice:FireServer(getDevice())Troubleshooting
Common issues and how to fix them.
No data appearing in the dashboard
Make sure "Enable Studio Access to API Services" is turned ON in Game Settings → Security. Without this, HTTP requests are blocked and no data can be sent.
HTTP 403 or "API key invalid" error
Double-check your API key in Dashboard → Game Settings. Make sure you copied the full key with no extra spaces. Each game has a unique key.
Device detection shows "unknown" for all players
Add the optional Client Script (LocalScript) to StarterPlayerScripts. The server SDK creates the BloxMetricsRemotes folder automatically — the client script just needs to be present.
Data appears in Studio but not in published game
After testing in Studio, make sure to Publish the game (File → Publish to Roblox). Also verify that API services are enabled for the published version, not just Studio.
Revenue/GamePass purchases not tracking
Ensure EnableRevenueTracking() is called in your init chain. For Developer Products, you must use BM:ProcessReceipt() as shown in the Revenue Tracking section.
SDK module not found / require() fails
Make sure you're using the correct Asset ID: 127217366828209. The require() call should be: require(127217366828209). Check that your game has access to load third-party modules.
BloxMetrics SDK v2.0 • Asset ID: 127217366828209
Need help? Reach out at hello@bloxmetrics.io