NetworkPro

Perform HTTP calls and store the response in run variables

One function, httpRequest, performs a synchronous HTTP call from inside a macro and returns the response as a { body, status, contentType } object.

TapForge Pro only. Without an active Pro subscription the call returns immediately with status === -1 and the body "Network requests require Pro". The check happens on every call, so a subscription that lapses mid-run will start failing future requests.

httpRequest(method, url, opts?)

Sends an HTTP request and returns the response object. Blocks the calling thread until the request completes or times out.

ParameterTypeDefaultDescription
methodstring—One of GET, POST, PUT, PATCH, DELETE. GET and DELETE ignore the body.
urlstring—Full URL. Only http:// and https:// are accepted; other schemes return status === -1.
opts.headersobject—Header map, e.g. { "Authorization": "Bearer ..." }.
opts.bodystring—Raw request body. JSON callers should JSON.stringify themselves.
opts.timeoutMsnumber10000Connect + read timeout in milliseconds. A value you pass is clamped to 100–30000; 0, like omitting it, means the 10000 ms default.

Returns { body: string, status: number, contentType: string }

// Simple GET
const r = httpRequest("GET", "https://api.example.com/weather?city=Berlin");
if (r.status === 200) {
  const data = JSON.parse(r.body);
  print("Temp:", data.temperature);
} else {
  print("Failed:", r.status);
}
// POST with JSON body and bearer auth
const r = httpRequest("POST", "https://hooks.example.com/notify", {
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer " + getGlobalVar("apiToken"),
  },
  body: JSON.stringify({ event: "macro_done", count: 5 }),
  timeoutMs: 5000,
});
if (r.status !== 200) print("notify failed:", r.status, r.body);

Visual Network Request step

The visual Network Request step (in the macro builder) wraps the same call but also writes the response into run variables so subsequent visual steps can interpolate ${var} without writing JS:

Run variableTypeContents
${varName}stringResponse body (or error message on failure).
${varName}_statusnumberHTTP status code, or -1 on network/Pro errors.
${varName}_contentTypestringContent-Type header from the server, or empty on failure.
These run-variable writes happen automatically for the visual step. If you're calling httpRequest directly from JS, use the returned object — there is no varName parameter in the JS API.

Errors & timeouts

The function never throws. Failures collapse into status === -1 with the error description in body:

const r = httpRequest("GET", "https://invalid.example.invalid/");
if (r.status === -1) {
  print("Network error:", r.body);   // e.g. "Unable to resolve host..."
  exit();
}

HTTP error codes (4xx, 5xx) come back with the real status and the server's error body — they are not treated as -1:

const r = httpRequest("GET", "https://httpbin.org/status/404");
print(r.status);   // → 404
print(r.body);     // → server error body (often empty)

Limits

  • Pro required on every call — defence in depth against runtime downgrades.
  • Marketplace upload is blocked for any macro containing a Network Request step. The server rejects publish and update with a failed-precondition error. Use it for your own automations; not for distribution.
  • Marketplace-imported macros can never reach the network, whatever the installer's Pro status. The check runs before the Pro gate and on the binding itself, so it holds however the call is spelled: every request returns status === -1 with body set to "Network requests are disabled for marketplace-imported macros".
  • http:// and https:// only. file:, jar:file:, and other schemes are rejected with status === -1 before any connection is opened.
  • Response body cap: 10 MB. Anything past the limit is silently truncated to protect against OOM.
  • Redirects are not followed. A 301/302 comes back as-is, and since only body, status and contentType are exposed, the Location header is not retrievable — request the final URL directly.
  • Private and loopback addresses are blocked with status === -1, so a macro cannot reach the device's own services or the local network.
  • PATCH is tunnelled as a POST with an X-HTTP-Method-Override: PATCH header; a server that ignores that header sees a POST.
  • Streaming, SSE, WebSocket, multipart, cookies — not supported. Request/response only.
  • No URL allowlist. Any Pro user can hit any endpoint with any credentials they choose to bake in — by design.