Appearance
HTTP node
IMPORTANT
This node is an installable component, not part of the engine. Every workspace gets it installed automatically; if it has been removed, the node passes straight through at run time and the editor marks it Not installed in the Add panel. Open Components in the project header to reinstall it.
It is the one component that declares network: ["*"] — it may contact any host, because a URL you choose is the entire point of it. That is now stated on its store listing. It was equally unrestricted as a built-in; you just couldn't see it.
The HTTP node calls an external API — a webhook, a REST endpoint, a third-party service — and stores the response so later nodes can read the status and body. It's the main way a flow reaches out to another system.
Component id: flowrunner/http. This is an I/O node: it makes a network request and can fail for reasons outside your flow, so it carries an error port.
How it works
The node builds and sends a fetch request:
- Method — from
method(defaultGET), upper-cased. - URL — from
url, with${env.X}and${secrets.X}resolved. A missing URL fails the node (http: missing url). - Headers — each value in
headersis resolved for${env.X}/${secrets.X}. - Body — only sent for methods other than
GET/HEAD, and only whenbodyis set. A string body is used as-is (after resolving${...}). A non-string body isJSON.stringify-ed, andContent-Type: application/jsonis added automatically unless you already set one.
The response is read as text and, if it parses as JSON, stored as parsed JSON — otherwise the raw text is kept. The node then stores an object under resultVar (default response):
text
{
status: <HTTP status number>,
ok: <true when status is 2xx>,
body: <parsed JSON, or raw text>
}Config
| Field | Required | Description |
|---|---|---|
url | Yes | The request URL. Resolves ${env.X} and ${secrets.X}. Missing URL fails the node. |
method | No (default GET) | HTTP method, e.g. GET, POST, PUT, PATCH, DELETE. |
headers | No | Object of header name → value. Each value resolves ${env.X} / ${secrets.X}. |
body | No | Request body (only sent for non-GET/HEAD). String bodies are sent verbatim; objects are JSON-encoded with an automatic Content-Type. |
resultVar | No (default response) | The variable the { status, ok, body } result is stored under. |
retries | No (default 0) | Retry a network error or a retryable status (408/425/429/5xx) up to this many times (max 5). See Retrying transient failures. |
retryDelayMs | No | Milliseconds to wait between retries. |
Ports
| Port | Followed when |
|---|---|
next | The request completed (any HTTP status — a 404 or 500 still counts as a completed request; check response.ok). |
error | The request threw — network failure, DNS error, timeout. The error message is http: <reason> and is also written to error.message. |
NOTE
A 404 or 500 response does not take the error port — the request succeeded, the server just answered with an error status. Branch on response.ok or response.status with an If node to handle those. The error port fires only when the request itself couldn't complete.
Example
Post a form submission to a CRM, authenticating with a secret:
text
HTTP method: POST url: https://crm.example.com/leads
headers: { Authorization: "Bearer ${secrets.CRM_TOKEN}" }
body: { email: start.email, name: start.name }
resultVar: crm
# read later as: crm.status, crm.ok, crm.body.idTIP
Keep API keys and tokens out of the URL and headers as plain text — store them as workspace secrets and reference them with ${secrets.NAME}.