Skip to content

HTTP Webhooks & External APIs

The HttpExporter sends batched telemetry payloads to any external HTTPS REST endpoint. It automatically handles exponential backoff retries and coalesces events into batches to stay well within Roblox’s engine budget (500 requests per minute per server).


Enable the HTTP exporter by specifying httpEndpoint and optional httpApiKey inside AnalyticsModule.init:

local Analytics = AnalyticsModule.init({
httpEndpoint = "https://telemetry.yourdomain.com/v1/events",
httpApiKey = "your-api-key-here",
batchSize = 25, -- Up to 25 events per HTTP payload
flushIntervalSeconds = 10, -- Flush every 10 seconds
})

Property Value
Method POST
Headers Content-Type: application/json
Auth Headers (if httpApiKey provided) Authorization: Bearer <key>
X-API-Key: <key>
Timeout 30 seconds (Roblox HttpService default)

The request body is a single JSON object containing server metadata, timestamp, and an array of serialized events:

{
"serverJobId": "d3b07384-d113-49d6-8488-e9f01509a243",
"placeId": 12345678,
"placeVersion": 4,
"sentAt": 1727790000,
"eventCount": 2,
"events": [
{
"name": "PlayerDeath",
"category": "spatial",
"timestamp": 1727790000,
"userId": 123456,
"sessionId": "b8f67389-1065-4f76-871d-15ec43194511",
"data": {
"position": { "x": 10.5, "y": 5.0, "z": -20.2 },
"causeOfDeath": "PvP",
"killerUserId": 987654
}
},
{
"name": "EconomySink",
"category": "economy",
"timestamp": 1727790000,
"userId": 123456,
"sessionId": "b8f67389-1065-4f76-871d-15ec43194511",
"data": {
"flowType": "Sink",
"currency": "Gold",
"amount": 50,
"itemId": "HealthPotion"
}
}
]
}

Network interruptions or temporary server restarts are handled gracefully:

  1. Attempt 1: Sent immediately when batch threshold is reached.
  2. Attempt 2 (if failed): Retried after $1\text{s}$ backoff ($1 \times 2^0$).
  3. Attempt 3 (if failed): Retried after $2\text{s}$ backoff ($1 \times 2^1$).
  4. If all 3 attempts fail, an error is printed to the console and the engine proceeds without crashing or blocking subsequent frames.

  • Roblox HttpService Limit: Roblox caps server requests at 500 HTTP requests per minute. Batching 25 events per request allows tracking up to 12,500 events per minute using only a fraction of the engine’s budget.
  • Roblox Secrets: Always store API keys in Roblox Secrets rather than hardcoding them in scripts:
local HttpService = game:GetService("HttpService")
local apiKey: string? = nil
local ok, secret = pcall(function()
return HttpService:GetSecret("analytics_api_key")
end)
if ok and secret then
apiKey = secret
end
local Analytics = AnalyticsModule.init({
httpEndpoint = "https://telemetry.yourdomain.com/v1/events",
httpApiKey = apiKey,
})