HTTP API
StationeersLua can make outbound HTTP requests through the ic.http namespace when the server enables it.
Server-Gated Feature
ic.http is disabled by default. The server admin must enable AllowHttp in the [Features] section before requests will succeed.
Server configuration
| Setting | Default | Description |
|---|---|---|
AllowHttp | false | Master toggle for outbound HTTP from Lua chips |
AllowHttpLocalhost | false | When AllowHttp is on, permits localhost and loopback literal URLs. Link-local addresses stay blocked even when this is enabled |
When AllowHttp is enabled, the mod blocks loopback and link-local literal URLs by default (SSRF guard). Set AllowHttpLocalhost = true only when you deliberately need chips to call services on the same machine (for example a local API on 127.0.0.1).
Request Flow
local requestId = ic.http.get("https://example.com/api/status")
while true do
local id, ok, status, body, err = ic.http.poll()
if id == requestId then
if ok then
print("status", status)
print(body)
else
print("http error", err)
end
break
end
yield()
endRequests are asynchronous:
- Start a request with
get,post,put,delete, orpatch - Store the returned request id
- Poll for completions with
ic.http.poll()inside your normaltick()oryield()loop
Request Functions
| Function | Returns | Description |
|---|---|---|
ic.http.get(url [, headers] [, timeout]) | request id | Start a GET request |
ic.http.post(url, body [, contentType] [, headers] [, timeout]) | request id | Start a POST request |
ic.http.put(url, body [, contentType] [, headers] [, timeout]) | request id | Start a PUT request |
ic.http.delete(url [, headers] [, timeout]) | request id | Start a DELETE request |
ic.http.patch(url, body [, contentType] [, headers] [, timeout]) | request id | Start a PATCH request |
ic.http.poll() | id, ok, status, body, err | Retrieve the next completed response |
URL Helper Functions
local params = {
device = "Main Sensor",
includeHistory = true,
limit = 20,
}
local query = ic.http.build_query(params)
local url = ic.http.build_url("https://example.com/api/readings", params)
print(query)
print(url)| Function | Returns | Description |
|---|---|---|
ic.http.url_encode(str) | string | Percent-encode a value |
ic.http.url_decode(str) | string | Decode a percent-encoded value |
ic.http.build_query(table) | string | Build a query string from a Lua table |
ic.http.build_url(base, params) | string | Build a full URL with query parameters |
Limits
HTTP limits are configurable by the server admin.
| Setting | Default | Description |
|---|---|---|
MaxConcurrentRequests | 8 | Maximum concurrent HTTP requests per chip host |
MaxRequestBodyKB | 64 | Maximum request body size |
MaxResponseBodyKB | 256 | Maximum response body size |
DefaultTimeoutSeconds | 10 | Default timeout when omitted |
MaxTimeoutSeconds | 30 | Maximum allowed timeout |
MaxCustomHeaders | 8 | Maximum custom headers per request |
MaxUrlLength | 2048 | Maximum URL length |
URL requirements
When AllowHttp is enabled:
- URLs must use
http://orhttps://(other schemes are rejected). localhostand loopback IPs (127.0.0.0/8,::1) are blocked unless[Features] AllowHttpLocalhostistrueon the host or dedicated server (typical for single-player or local tools on the same machine).- Link-local addresses (including
169.254.169.254) are always blocked. - Private LAN addresses (RFC1918) are allowed so scripts can reach devices on your base network.
| Setting | Default | Description |
|---|---|---|
AllowHttp | false | Master toggle for ic.http |
AllowHttpLocalhost | false | When AllowHttp is true, also permit localhost and loopback URLs |
Hostname-only URLs that resolve to blocked ranges are not checked at enqueue time; use literal IPs or public hostnames when you need predictable behavior.
Tips
- Keep request/response bodies small
- Always handle failure paths from
ic.http.poll() - Use the URL helper functions instead of hand-building query strings when values may contain spaces or symbols
- Poll inside a normal
yield()/tick()loop instead of blocking other chip work
