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).
Configuration
Section titled “Configuration”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})HTTP Request Specification
Section titled “HTTP Request Specification”| 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) |
Payload Schema
Section titled “Payload Schema”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" } } ]}Retry Policy & Rate Limit Backoff
Section titled “Retry Policy & Rate Limit Backoff”Network interruptions or temporary server restarts are handled gracefully:
- Attempt 1: Sent immediately when batch threshold is reached.
- Attempt 2 (if failed): Retried after $1\text{s}$ backoff ($1 \times 2^0$).
- Attempt 3 (if failed): Retried after $2\text{s}$ backoff ($1 \times 2^1$).
- If all 3 attempts fail, an error is printed to the console and the engine proceeds without crashing or blocking subsequent frames.
Engine Quotas & Best Practices
Section titled “Engine Quotas & Best Practices”- 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? = nillocal ok, secret = pcall(function() return HttpService:GetSecret("analytics_api_key")end)if ok and secret then apiKey = secretend
local Analytics = AnalyticsModule.init({ httpEndpoint = "https://telemetry.yourdomain.com/v1/events", httpApiKey = apiKey,})