HTTP
The core.http module provides asynchronous HTTP requests from Lua scripts. Requests run in the background and deliver results via callbacks on the main thread, so they never block game logic.
Async Callbacks
Responses are delivered on the next game tick after they complete. Your callback will not fire immediately — it runs when the main thread polls for results.
Per-Script Isolation
Cookies and authentication state persist within a script's own requests but never leak between scripts. Two scripts talking to the same host hold their own separate state — calls from one script never see headers, cookies, or auth from another.
A script can also create additional clients explicitly via core.http.client() when it needs more than one independent HTTP context (e.g. two separate auth contexts, or isolated bot vs telemetry traffic).
Functions
All functions take a callback as the last argument. The callback receives a single response table.
core.http.get(url: string [, headers: table], callback: function)
Sends a GET request.
core.http.get("https://api.example.com/data", function(response)
core.log("Status: " .. response.status)
core.log("Body: " .. response.body)
end)core.http.post(url: string, body: string [, content_type: string [, headers: table]], callback: function)
Sends a POST request. content_type defaults to "application/json".
core.http.post("https://api.example.com/data", '{"key":"value"}', function(response)
core.log("Status: " .. response.status)
end)core.http.put(url: string, body: string [, content_type: string [, headers: table]], callback: function)
Sends a PUT request. content_type defaults to "application/json".
core.http.delete(url: string [, headers: table], callback: function)
Sends a DELETE request.
core.http.request(method: string, url: string [, body: string [, headers: table]], callback: function)
Sends a request with any HTTP method.
core.http.request("PATCH", "https://api.example.com/data", '{"updated":true}', function(response)
core.log("Status: " .. response.status)
end)Explicit Clients
core.http.client() returns a brand-new client object with its own cookie jar, auth state, and connection pool — fully isolated from your script's default client and from any other clients you create.
Use this when one script needs multiple independent HTTP contexts. The methods on the returned object mirror the free functions exactly, just with : instead of ..
local api = core.http.client()
local logs = core.http.client()
api:get("https://api.example.com/login", function(r) ... end)
logs:post("https://logs.example.com/ingest", payload, function(r) ... end)Cookies set on api will never be sent by logs, and vice versa. The same applies to authentication.
Methods
The client object supports the same five verbs as the free functions:
client:get(url [, headers], callback)
client:post(url, body [, content_type [, headers]], callback)
client:put(url, body [, content_type [, headers]], callback)
client:delete(url [, headers], callback)
client:request(method, url [, body [, headers]], callback)The client lives until your script unloads or until you let go of all references to it (Lua GC closes the underlying session and aborts any in-flight requests on it).
Response Object
The callback receives a table with the following fields:
| Field | Type | Description |
|---|---|---|
status | number | HTTP status code (200, 404, etc.) or 0 if the request failed |
body | string | Response body as a string |
headers | table | Response headers as key-value pairs |
Custom Headers
Pass a table of string key-value pairs before the callback to set request headers.
core.http.get("https://api.example.com/data", {
["Authorization"] = "Bearer my-token",
["Accept"] = "application/json"
}, function(response)
core.log(response.body)
end)Examples
Simple GET
local has_run = false
function on_tick()
if has_run then return end
has_run = true
core.http.get("https://httpbin.org/get", function(response)
core.log("Status: " .. response.status)
core.log("Body: " .. string.sub(response.body, 1, 200))
end)
endPOST JSON Data
core.http.post("https://api.example.com/webhook",
'{"event":"evasion","player":"SomeName"}',
"application/json",
{ ["Authorization"] = "Bearer token123" },
function(response)
if response.status == 200 then
core.log("Webhook sent successfully")
else
core.log_error("Webhook failed: " .. response.status)
end
end
)Discord Webhook
function on_evasion(player_names)
local names = table.concat(player_names, ", ")
local payload = '{"content":"Evasion triggered by: ' .. names .. '"}'
core.http.post("https://discord.com/api/webhooks/YOUR_WEBHOOK_URL",
payload,
"application/json",
function(response)
if response.status ~= 204 then
core.log_error("Discord webhook failed: " .. response.status)
end
end
)
endReading Response Headers
core.http.get("https://httpbin.org/response-headers?X-Custom=hello", function(response)
for name, value in pairs(response.headers) do
core.log(name .. ": " .. value)
end
end)