Skip to content

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.

lua
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".

lua
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.

lua
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 ..

lua
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:

lua
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:

FieldTypeDescription
statusnumberHTTP status code (200, 404, etc.) or 0 if the request failed
bodystringResponse body as a string
headerstableResponse headers as key-value pairs

Custom Headers

Pass a table of string key-value pairs before the callback to set request headers.

lua
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

lua
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)
end

POST JSON Data

lua
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

lua
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
    )
end

Reading Response Headers

lua
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)