perch.http.get exists only if your manifest declares at least one
net.http:<host> scope — and reaches only those hosts. It is the entire
network surface: no sockets, no POST, no websockets, by design.
"scopes": ["net.http:api.open-meteo.com", "timer"]
perch.http.get(url, callback, opts?)
perch.http.get("https://api.open-meteo.com/v1/forecast?latitude=35.7&longitude=139.7¤t=temperature_2m",
function(status, body)
if status ~= 200 then return end
local data = perch.json.decode(body)
if not data then return end
host_ref.push_data("mywx", { temp = math.floor(data.current.temperature_2m + 0.5) .. "°" })
end)
Fully async: a C++ worker performs the fetch off-thread; your callback lands on the main thread later. Lua never blocks, and no budget is spent waiting.
The callback
callback(status, body):
status | Meaning |
|---|---|
200–599 | the HTTP status; body = response (capped) |
-1 | refused or failed: body = "scope" (unpinned host / not https), "rate" (hourly cap), "unavailable", or empty when the request went out but the network failed (no response) |
opts
{ ua = "<string>" } overrides the default perch-mod/<id> user agent —
some public APIs demand a browser UA. The override is manifest-visible
behavior; use it because an API requires it, not to disguise traffic.
The caps
| Cap | Value |
|---|---|
| scheme | https:// only |
| host | exact match against a pinned scope — no subdomain wildcards |
| rate | 30 requests per hour per mod, rolling window |
| body | 1 MB — larger responses are truncated at the cap |
A 2-minute poll is the entire budget — one retry tips it. Design for
5+ minutes with on_page_visibility gating: poll fast only while your
page is actually visible.
local visible = false
function M.on_page_visibility(host, widget, v)
visible = v
host.timer("poll", (v and 5 or 30) * 60 * 1000)
end
Failure is normal
Networks flake. The pattern every builtin uses:
- Keep the last good payload in a file-level local (or
perch.storageif it should survive restarts). - On failure, keep showing it — maybe with a quiet staleness hint.
- Never
set_presence(false)because one fetch failed — a configured slot showing yesterday’s data beats a hole.