HTTP Requests Tool — Complete Guide

The HTTP Requests tool turns your dashboard into a built-in API client — like a mini Postman that lives inside Virtuino Cloud. You can call any public REST API, test it live, and then have the server run it automatically (on a schedule or when a field changes) and feed the response straight into your fields and scripts.

Where to find it: open a dashboard, unlock it (edit mode), then click Tools  → HTTP Requests. Press new request to open the editor.
This tool is for the dashboard owner. Saving, editing and deleting requests requires you to be logged in as the owner. Shared/guest viewers cannot modify requests.

Contents

  1. Anatomy of a request
  2. Params tab
  3. Authorization tab — None · Bearer · Basic · API Key
  4. Headers tab
  5. Body tab — JSON · form · raw
  6. The Test button & reading results
  7. Automation — Polling · Trigger · Store output
  8. Worked example A — Weather temperature
  9. Worked example B — Weather multi-value
  10. Security & limits
  11. Troubleshooting & FAQ
About the test endpoints in this guide. The examples below use two free, public services so you can run them with the Test button immediately:

1. Anatomy of a request

Every request you build has the same top section, regardless of the tabs you fill in:

FieldWhat it does
titleA friendly name shown in the list (e.g. Athens weather). Has no effect on the call.
methodThe HTTP verb: GET POST PUT PATCH DELETE. GET retrieves data; POST/PUT/PATCH send a body; DELETE removes.
urlThe full endpoint, starting with http:// or https://.
TestRuns the request immediately through the server and shows the live response below — without saving.

Below the URL there are four tabs that shape the request: Params, Authorization, Headers and Body. The second top-level tab, automation, is covered in section 7.

2. Params tab

Query parameters are the ?key=value&key2=value2 part of a URL. Instead of typing them by hand, add them as rows here — each enabled row is appended to the URL, correctly URL-encoded.

ColumnMeaning
(checkbox)Include this row in the request. Uncheck to keep a param without sending it.
KeyParameter name (e.g. latitude).
ValueParameter value (e.g. 37.98).

Try it — echo your params

GET   https://httpbin.org/get

Params:

KeyValue
cityAthens
unitsmetric

Press Test. httpbin echoes the parameters it received under args:

{
  "args": {
    "city": "Athens",
    "units": "metric"
  },
  "url": "https://httpbin.org/get?city=Athens&units=metric"
}
If your args match what you typed, the Params tab is working. The final url shows exactly what was called.

3. Authorization tab

Many APIs require credentials. Choose the type and the tool builds the correct header for you. The credentials are stored with the request and sent on every (manual or automatic) run.

3a. No Auth

The default. Nothing is added. Use it for open APIs like Open-Meteo.

3b. Bearer Token

Adds the header Authorization: Bearer <token>. This is the most common scheme for modern APIs (OAuth2, personal access tokens, etc.).

Try it — Bearer

GET   https://httpbin.org/bearer

Authorization: Bearer Token → token = my-secret-123

{
  "authenticated": true,
  "token": "my-secret-123"
}

3c. Basic Auth

Adds Authorization: Basic <base64(username:password)>. The tool does the Base64 encoding for you.

Try it — Basic

GET   https://httpbin.org/basic-auth/admin/s3cret

Authorization: Basic Auth → username = admin, password = s3cret

{
  "authenticated": true,
  "user": "admin"
}
The URL /basic-auth/admin/s3cret tells httpbin which credentials to accept. If you type the wrong username/password in the Auth tab, you get 401 Unauthorized — try it to see the failure case.

3d. API Key

Sends a custom header of your choice, e.g. X-API-Key: <value>. Set the header name and the value. Many weather/finance APIs use this style.

Try it — API Key (as a header)

GET   https://httpbin.org/headers

Authorization: API Key → header name = X-API-Key, value = abc123

{
  "headers": {
    "Host": "httpbin.org",
    "X-Api-Key": "abc123"
  }
}
Some APIs instead expect the key as a query parameter (e.g. ?apikey=abc123). In that case leave Authorization on No Auth and add the key in the Params tab instead.

4. Headers tab

Custom request headers, added as key/value rows (same layout as Params). Use them for content negotiation, custom tokens, or anything the API documents. Common examples:

HeaderTypical use
Accept: application/jsonAsk the server to return JSON.
User-Agent: VirtuinoCloudIdentify your client.
X-Custom-Token: ...Any vendor-specific header.

Try it — custom headers

GET   https://httpbin.org/headers

Headers:

KeyValue
Acceptapplication/json
X-Demovirtuino
{
  "headers": {
    "Accept": "application/json",
    "X-Demo": "virtuino",
    "Host": "httpbin.org"
  }
}
Auth vs Headers: the Authorization tab is just a convenient way to build the Authorization header. Anything you can do there you could also type manually in Headers — but the Auth tab is safer and clearer.

5. Body tab

The body is the payload you send to the server. It only applies to POST, PUT and PATCH — for GET/DELETE it is ignored. Choose one of four modes:

ModeWhat is sentContent-Type set
noneNo body.
JSONA raw JSON document you type.application/json
form-urlencodedKey/value pairs encoded as a=1&b=2.application/x-www-form-urlencoded
rawAny plain text (XML, CSV, etc.).none (set your own in Headers)

Try it — POST JSON

POST   https://httpbin.org/post

Body → JSON:

{
  "device": "pump-1",
  "command": "on",
  "value": 42
}

httpbin returns what it parsed under json:

{
  "json": { "device": "pump-1", "command": "on", "value": 42 },
  "headers": { "Content-Type": "application/json" }
}

Try it — POST form-urlencoded

POST   https://httpbin.org/post

Body → form-urlencoded:

KeyValue
relay1
duration30
{
  "form": { "relay": "1", "duration": "30" }
}

6. The Test button & reading results

The Test button sends the request immediately through the Virtuino server (never from your browser — that avoids CORS problems and applies our security checks). The results panel shows:

Testing does not save the request and does not write to any field. It is purely a dry run so you can confirm the URL, auth, headers and body are correct before enabling automation.

7. Automation

Switch to the automation tab to make the request run by itself on the server. There are three independent cards — enable any combination with the checkbox at the top of each.

7a. Polling

Runs the request on a fixed schedule. Set the interval in minutes (1–1440, i.e. up to 24 hours). The server executes the request every interval and — if Store output is on — saves the response to your field.

Polling is ideal for data that changes slowly and predictably: weather, exchange rates, daily quotas, a status endpoint, etc.

7b. Trigger

Runs the request when one of your fields meets a condition. Pick a device + field, a condition, and a value:

ConditionFires when the field value is…
greater than >strictly above the value
less than <strictly below the value
greater or equal ≥at or above the value
less or equal ≤at or below the value
equal ==exactly equal
not equal !=anything except the value
changedany time the value actually changes (the value box is ignored)
Edge-triggered: comparison conditions fire once when the condition becomes true, and re-arm only after it becomes false again — so a field that stays above the threshold will not spam the API on every update. changed fires on each genuine change of value.

7c. Store output

Pick a device + field where the raw response is written after each run (polling or trigger). The value flows through the same engine as everything else, which means:

The output field can be the trigger of an Automation Script. Create a script (Tools → Scripts) with this output field as its trigger input, parse the JSON inside the script, and write the extracted numbers to any fields you like. This is the recommended way to extract specific values — see the worked examples below.
Use a standard (non-historical) field — never a historical one. Historical fields are capped at 512 characters, so a normal JSON response would be rejected and the field would stay empty. A standard field holds up to 1 MB and overwrites on each run, which is exactly what you want here. The response is stored as text; request only the data you need (see the size limits).

8. Worked example A — Weather temperature

Goal: every minute, fetch the current temperature for Athens and store it in a numeric field.

Step 1 — Build & test the request

GET   https://api.open-meteo.com/v1/forecast?latitude=37.98&longitude=23.73&current=temperature_2m

(Equivalently, put the URL up to /forecast and add latitude, longitude, current in the Params tab.) Press Test — you should get:

{
  "latitude": 37.98,
  "longitude": 23.72,
  "current": {
    "time": "2026-06-20T10:00",
    "interval": 900,
    "temperature_2m": 27.8
  }
}

Step 2 — Automation

Step 3 — The parsing script

Create an Automation Script with two variables: in1_variable (IN, mapped to weather_raw, marked as trigger) and out1_variable (OUT, mapped to your temperature field).

// Title: Open-Meteo Temperature Extractor
// in1_variable  -> IN  : the field holding the raw JSON (trigger)
// out1_variable -> OUT : the destination temperature field

const raw = (inputs.in1_variable && inputs.in1_variable.value) ? inputs.in1_variable.value : "";

if (typeof raw !== "string" || raw.trim() === "") {
    console.log("in1_variable empty - run the request first.");
} else {
    try {
        const data = JSON.parse(raw);
        const t = (data && data.current) ? data.current.temperature_2m : undefined;
        if (t !== undefined && t !== null) {
            outputs.out1_variable = t;
            console.log("Temperature -> " + t);
        } else {
            console.log("temperature_2m not found.");
        }
    } catch (e) {
        console.log("Parse error: " + e.message);
    }
}

That's the whole pipeline: request → weather_raw → script → temperature field, refreshing every minute.

9. Worked example B — Weather multi-value

Goal: pull temperature, humidity and wind in one call and split them into three fields.

Step 1 — Request

GET   https://api.open-meteo.com/v1/forecast?latitude=37.98&longitude=23.73&current=temperature_2m,relative_humidity_2m,wind_speed_10m

{
  "current": {
    "temperature_2m": 27.8,
    "relative_humidity_2m": 41,
    "wind_speed_10m": 12.6
  }
}

Step 2 — Automation

Step 3 — The multi-output script

Variables: in1_variable (IN, weather_raw, trigger), out1_variable/out2_variable/out3_variable (OUT, mapped to temperature / humidity / wind fields).

// Title: Open-Meteo Weather Parser (multi-value)
// in1_variable  -> IN  : raw JSON field (trigger)
// out1_variable -> OUT : temperature
// out2_variable -> OUT : humidity
// out3_variable -> OUT : wind speed

const raw = (inputs.in1_variable && inputs.in1_variable.value) ? inputs.in1_variable.value : "";

if (typeof raw !== "string" || raw.trim() === "") {
    console.log("in1_variable is empty - run the request first.");
} else {
    try {
        const data = JSON.parse(raw);
        const cur  = (data && data.current) ? data.current : null;

        if (!cur) {
            console.log("No 'current' object in response.");
        } else {
            if (cur.temperature_2m       !== undefined && cur.temperature_2m       !== null) outputs.out1_variable = cur.temperature_2m;
            if (cur.relative_humidity_2m !== undefined && cur.relative_humidity_2m !== null) outputs.out2_variable = cur.relative_humidity_2m;
            if (cur.wind_speed_10m       !== undefined && cur.wind_speed_10m       !== null) outputs.out3_variable = cur.wind_speed_10m;

            console.log("temp: " + cur.temperature_2m + " | hum: " + cur.relative_humidity_2m + " | wind: " + cur.wind_speed_10m);
        }
    } catch (e) {
        console.log("JSON parse error: " + e.message);
    }
}
Scripting rule — no top-level return. Scripts run in a sandboxed isolate that evaluates your code directly, so a bare return; at the outermost level is a syntax error. Wrap your logic in if/else or try/catch as shown above. Inside a function, return is fine.

10. Security & limits

Time limits

LimitValueWhy
Request timeout10 secondsA slow/hanging endpoint is aborted so it can't block the server.
Polling interval1 minute min · 1440 (24 h) maxYou choose the cadence per request, within these bounds.
Trigger cooldownonce per 10 s per requestIf the trigger field oscillates or changes many times per second, the request still fires at most once every 10 s — it can never flood the external API.

Size limits

StageLimitWhat happens if exceeded
Response download1 MBThe request is rejected — request only the data you need from the API.
Stored to a standard field1 MBMatches the download cap, so any response that downloaded also fits the field.
Stored to a historical field512 charactersAnything longer is rejected — see the warning below.
Saved in the execution logs4000 charactersThe stored response is truncated (the live response itself is not).
⚠️ The output field must NOT be a historical field. Historical fields keep every value forever, so they are deliberately capped at 512 characters — far too small for a typical JSON API response, which would be rejected entirely (your script would then see an empty field). Always point Store output at a standard (non-historical) field, which holds up to 1 MB and overwrites on each run. Parse out the small numbers you care about in your script and write those to historical fields if you want a history.

Security

11. Troubleshooting & FAQ

The list shows small icons next to a request — what are they?

polling enabled  ·  trigger enabled  ·  stores output to a field.

Test works, but nothing happens automatically.

Check that (1) the relevant card's checkbox in the automation tab is on and the request is saved; (2) for Store output, a device and field are selected; (3) for triggers, the field really updates and the condition is met.

My script never runs after the response is stored.

Make sure the script's input variable is mapped to the same field chosen in Store output, and that the mapping is marked as the trigger. Confirm the script is Active and Ready.

Parse error in the script.

The output field doesn't yet hold valid JSON. Run the request once (Test or wait for a poll) so the field is populated, then the script will parse it on the next update.

How do I send the API key as a query parameter instead of a header?

Leave Authorization on No Auth and add the key as a row in the Params tab (e.g. apikey = ...).

Putting it together: HTTP Request fetches data → Store output drops the raw JSON into a field → an Automation Script parses it into clean values → your widgets display them, and rules can alert on them. One tool, fully wired into the rest of Virtuino Cloud.

Virtuino Cloud — HTTP Requests Tool