Docs
License keys & in-game checks
Products marked 🔑 License key come with a unique key, which you'll find in your library right after purchase. Some systems check the key when your server starts, so keep it in a server-only script.
1. Enable HTTP requests
In Roblox Studio open Game Settings → Security and turn on Allow HTTP Requests.
2. Add the LicenseCheck module
Create a ModuleScript named LicenseCheck in ServerScriptService:
--!strict
-- LicenseCheck: verifies a TP Interactive license key from a Roblox server.
-- Place this ModuleScript in ServerScriptService (NOT ReplicatedStorage).
-- Requires: Game Settings > Security > "Allow HTTP Requests" = ON.
local HttpService = game:GetService("HttpService")
local LicenseCheck = {}
local ENDPOINT = "https://shop.tpinteractive.de/api/license/validate"
local cache: { [string]: boolean } = {}
-- productSlug: the product's URL name, e.g. "advanced-combat-system"
-- licenseKey: the key from your library at https://shop.tpinteractive.de/library
function LicenseCheck.validate(productSlug: string, licenseKey: string): (boolean, string?)
local cacheKey = productSlug .. ":" .. licenseKey
if cache[cacheKey] ~= nil then
return cache[cacheKey]
end
local ok, response = pcall(function()
return HttpService:RequestAsync({
Url = ENDPOINT,
Method = "POST",
Headers = { ["Content-Type"] = "application/json" },
Body = HttpService:JSONEncode({
product = productSlug,
license_key = licenseKey,
place_id = game.PlaceId,
}),
})
end)
if not ok then
-- Network error: fail open so an outage never breaks your live game.
warn("[LicenseCheck] request failed:", response)
return true, "network_error"
end
local success, data = pcall(HttpService.JSONDecode, HttpService, response.Body)
if not success or typeof(data) ~= "table" then
return true, "bad_response"
end
local valid = data.valid == true
cache[cacheKey] = valid
return valid, data.reason
end
return LicenseCheck3. Check the key before your system starts
-- Script in ServerScriptService
local LicenseCheck = require(script.Parent.LicenseCheck)
local valid, reason = LicenseCheck.validate("advanced-combat-system", "TP-XXXXX-XXXXX-XXXXX-XXXXX")
if not valid then
warn("License invalid:", reason)
return -- stop the system from loading
end
-- ...start your system hereAPI
POST /api/license/validate with JSON { "product": "<slug>", "license_key": "<key>" } returns { "valid": true } or { "valid": false, "reason": "…" }. Results are cached for a few minutes.
Rules
- One key per purchase. Use it in your own games and keep it private.
- Never put the key in a LocalScript or ReplicatedStorage, because exploiters can read those.
- Refunded purchases deactivate the key.