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 into fields, no code
  9. Worked example B — The same with a script
  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.

Logs — what happened on the automatic runs

The logs button at the bottom of the editor shows the last 5 automatic runs (polling or trigger — not tests): when, how long it took, the status code or error, and the start of the response (up to 4000 characters). It is the first place to look when a saved request does not seem to do anything.

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 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. The comparison is numeric, like in rules.

7c. Store output

Pick the field where the raw response is written after each run (polling or trigger):

Getting single values out of the response. The easiest way needs no code: a JSON Splitter (dashboard → Tools → JSON Splitter) with the output field as its source, and one row per value — e.g. path current/temperature_2m → field weather/temperature. For calculations or conditions, use a script with the output field as its trigger input. Both are shown in 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 into fields, no code

Goal: fetch the current temperature, humidity and wind for Athens every 15 minutes and keep each in its own field, with history — using only the HTTP Request and a JSON Splitter.

Step 1 — Create the fields

In Console → Fields create:

Step 2 — Build & test the request

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

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

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

Step 3 — Automation

Step 4 — The JSON Splitter

In the dashboard, Tools → JSON Splitter → new splitter. Source field weather/raw, leave time path empty, and add three rows:

Path in the JSONField
current/temperature_2mweather/temperature
current/relative_humidity_2mweather/humidity
current/wind_speed_10mweather/wind

That's the whole pipeline: request → weather/raw → JSON Splitter → three fields, every 15 minutes. Put the three fields on widgets, or add a rule on weather/wind to be warned of strong wind.

9. Worked example B — The same with a script

Use a script instead of the JSON Splitter when you need more than copying numbers: a conversion, a condition, a calculated value. Steps 1–3 stay the same.

Step 4 — The script

Tools → Scripts → add script, then map the fields:

IOJS variableFieldOptions
INrawweather/rawtrg
OUTtemperatureweather/temperature—
OUThumidityweather/humidity—
OUTwindweather/wind—
let data;
try {
    data = JSON.parse(inputs.raw.value);
} catch (e) {
    return;                                  // not JSON yet
}
const cur = data.current || {};
if (typeof cur.temperature_2m === 'number')       outputs.temperature = cur.temperature_2m;
if (typeof cur.relative_humidity_2m === 'number') outputs.humidity    = cur.relative_humidity_2m;
if (typeof cur.wind_speed_10m === 'number')       outputs.wind        = cur.wind_speed_10m;

A value that is missing from the response is simply not written, so its field keeps its last value. Extend the code as you need — for example write wind in Beaufort instead of km/h. See the Scripts guide for everything a script can do.

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.
Cooldown10 s per requestIf the trigger field oscillates or changes many times per second, the request still runs at most once every 10 s — triggers in between are skipped — so 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.

Open the logs of the request first — they show every automatic run and its result. Then check that (1) the relevant card's checkbox in the automation tab is on and the request is saved; (2) for Store output, a field is selected; (3) for triggers, the field really updates, the condition is met, and the value does not come from a rule or over HTTP (7b).

The output field keeps an old value.

Only successful responses (200–299) are stored. If the API answers with an error, the field keeps its last good value — the logs show the status code and the error message.

My script or JSON Splitter never runs after the response is stored.

The script's input — or the splitter's source — must be the same field chosen in Store output, and for a script that input must have trg ticked. The script's icon must be green (active and complete mapping) — see Scripts — troubleshooting.

The output field is empty or a value is rejected.

The output field is historical. Historical fields take at most 512 characters, so a JSON response is rejected — use a standard field for the raw response.

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 → a JSON Splitter or a script turns 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