HTTP
The http library sends asynchronous HTTP requests: http.get, http.post, and http.request for PUT, DELETE, PATCH and HEAD. Requests run on background threads, so they never block your script. Each response comes back to your callback on the next tick.
Kill switch
To turn HTTP off, open Dev Studio (the bug icon in the navbar), go to the Security panel on the General page, and turn off Allow Lua HTTP Requests. It is on by default. When it is off, every http.get, http.post and http.request fails immediately with error = "http requests are disabled". A script cannot bypass it.
http.get(url, opts, callback)
Signatures:
http.get(url, opts, callback)
http.get(url, callback)The two-argument form omits opts and uses all defaults (no custom headers, default timeout, default user-agent).
Parameters:
url(string). The URL to request.opts(table, optional). Configuration:headers(table). Key-value pairs of request headers.user_agent(string). Custom User-Agent string. Default:"TsukiLua/1.0".timeout(number). Request timeout in milliseconds. Default:5000.
callback(function). Called with a response table when the request completes.
Examples:
-- With opts
http.get("https://api.example.com/data", {
headers = {
["Authorization"] = "Bearer my_token",
["Accept"] = "application/json"
},
timeout = 3000
}, function(res)
if res.ok then
print("Got:", res.body)
else
print("Failed:", res.status, res.error)
end
end)-- Without opts (two-argument form)
http.get("https://api.example.com/data", function(res)
if res.ok then
print("Got:", res.body)
end
end)http.post(url, opts, callback)
Signatures:
http.post(url, opts, callback)
http.post(url, callback)The two-argument form omits opts, sends no body and uses all defaults.
Parameters:
url(string). The URL to request.opts(table, optional). Configuration:headers(table). Key-value pairs of request headers.body(string). The request body content.user_agent(string). Custom User-Agent string. Default:"TsukiLua/1.0".timeout(number). Request timeout in milliseconds. Default:5000.
callback(function). Called with a response table when the request completes.
Examples:
-- With opts
http.post("https://api.example.com/submit", {
headers = {
["Content-Type"] = "application/json"
},
body = '{"username": "player1", "score": 100}'
}, function(res)
if res.ok then
print("Submitted successfully")
else
print("Error:", res.status, res.error)
end
end)-- Without opts (two-argument form)
http.post("https://api.example.com/ping", function(res)
print("Status:", res.status)
end)http.request(method, url, opts, callback)
Sends a request with any of these methods: "GET", "POST", "PUT", "DELETE", "PATCH" or "HEAD" (any case). Anything else raises an error.
Signatures:
http.request(method, url, opts, callback)
http.request(method, url, callback)opts and the response table are the same as for http.post. GET and HEAD send no body. The others send opts.body when you give one.
http.request("PUT", "https://api.example.com/items/7", {
headers = { ["Content-Type"] = "application/json" },
body = json.encode({ name = "renamed" }),
}, function(res)
print("PUT:", res.status)
end)
http.request("DELETE", "https://api.example.com/items/7", function(res)
print("DELETE:", res.ok)
end)Response table
The callback receives one table with these fields:
| Field | Type | Description |
|---|---|---|
status | number | HTTP status code (200, 404, etc.). 0 if the connection failed entirely. |
body | string | Response body as a string. Truncated to 1 MB if larger. |
ok | boolean | true if status is in the 200-299 range. |
error | string | Transport-level error message (DNS failure, connection refused, timeout, TLS failure). Empty whenever the server answered, even with a non-2xx status. For example, a 404 comes back as status = 404, ok = false, error = "". To detect an HTTP error status, check res.ok or res.status. res.error ~= "" only catches requests that never reached the server. |
Limits
- At most 4 requests can run at the same time, counted across every loaded script. Past that, the callback fires immediately, inside the
http.get,http.postorhttp.requestcall, withstatus = 0,body = "",ok = falseanderror = "too many concurrent requests". - The default timeout is 5 seconds. You can change it per request with
opts.timeout. - Response bodies are capped at 1 MB.
- The callback is required. A call without a callback function raises an error.
- SSL certificate verification is always on and cannot be turned off.
optsaccepts onlyheaders,body,user_agentandtimeout. There is noverify_sslflag. A host with a bad or self-signed certificate fails with a TLS error inresponse.error.
Notes
- Callbacks run at the start of the next tick after the request completes, not during
on_tick. - Callbacks run on the same thread as your script. Inside one,
config.*,storage.*,printandui.*act for your script, as inon_tick. - If a response arrives while your script is turned off, or after it has errored, it is dropped and the callback is not called. A paused script (its
is_enabled()returns false, or it is for another hero) still gets its responses. - Reloading (the Reload button, or saving a file) restarts the Lua VM and discards any callback still in flight.
- For JSON APIs, use
http.postwithContent-Type: application/json. Thebodyfield is sent as-is. Build it withjson.encodeand read replies withjson.decode.