HTTP and the web

The three nodes on this page solve three different problems, and confusing them is expensive: http_request calls any API as a graph step, fetch_webpage lets an agent read a page behind a link it already has, and websearch searches the internet and returns the model’s answer together with the sources and text excerpts from them.

None of them needs a connection: there is no login and no server to remember. A third-party API key lives not in a connection but in a workspace secret and is substituted through a template.

http_request — the universal door outward

This is the one node that makes an arbitrary HTTP request: method, address, headers, query parameters, body. Anything the platform has no dedicated integration for is done with it — from an internal company service to an API we have never heard of.

Entry
HTTP Request▶
Answer▶
Exit▶
The usual shape: the entry supplies data, the request goes out, a template parses the answer.
  • Execute + Data

What you configure

FieldValuesNote
MethodGET, POST, PUT, PATCH, DELETE, HEADGET and HEAD send no body, whatever sits in Body
URLhttp/httpstemplated
HeadersJSON objectthe whole field is templated, not just the values
Query ParametersJSON objectnumbers and booleans are stringified for you
Body typenone · json · text · formform is application/x-www-form-urlencoded, written as a JSON object
Bodystringtemplated; for json it must be valid JSON after substitution
Authorizationnone · bearer · basic · custom headerfills the Authorization header for you
Timeout1…120 seconds, 30 by defaulta plan may lower the ceiling, never raise it
Max response size (bytes)1 KiB…10 MB, 1 MB by defaulta longer response is truncated
Follow redirectsonevery hop is re-checked
Parse JSON Responseonthe body is decoded only if the server declared JSON
Fail on 4xx/5xxonturn it off when a 404 is a normal answer for you

Templates and secrets

The address, headers, parameters, body and the auth fields all go through the template engine. So {{ inputs.input }}, {{ nodes.<id>.output.<field> }} and {{ secret.NAME }} all work in them.

URL      https://api.example.com/v1/orders/{{ inputs.input.order_id }}
Headers  {"X-Api-Key": "{{ secret.SHOP_API_KEY }}"}
Body     {"comment": {{ nodes.llm_1.output | tojson }}}

The key lives in Settings → Secrets, not in the graph. This is not hygiene for its own sake: a graph can be exported, shown to a colleague or handed to the assistant, and a token pasted straight into its JSON travels with it.

What the node passes on

The response arrives as a single object. {{ nodes.<id>.output }} is that whole object.

FieldWhat is inside
status_codethe response code as a number
oktrue for 2xx
bodyparsed JSON when the server sent JSON and parsing is on; otherwise a string
textthe raw response text, always
headersresponse headers
urlthe final address after every redirect
elapsed_msround-trip time in milliseconds

Here the error branch is on by default

On most nodes the on_error output is off and has to be enabled by hand (see Node errors). On http_request it is on from the start — it is the only node in the catalogue with that default, and the reason is the nature of the job.

Somebody else’s server answers 500, returns 429, goes silent until the timeout or drops the connection. That is not a bug in your scenario, it is a normal, expected outcome of calling somebody else’s infrastructure. With the branch off, the single most common failure in the product would always end the same way: the whole run dies, the person in the chat gets nothing, and the author finds out from the run list. With the branch on, you decide — say “the service is unavailable, try later”, fall back to another source, mail yourself.

HTTP Request▶
Answer▶
Service unavailable▶
Exit▶
The error and success outputs exclude each other: exactly one fires, so both branches may safely meet at one exit.
  • Execute + Data

What routes control into the error branch: a network failure, a timeout, and — while Fail on 4xx/5xx is on — any non-2xx answer. Turn that toggle off when the status code is data to you (a 404 meaning “no such customer”): the node then always takes the success path and you branch on {{ nodes.<id>.output.ok }} with an ordinary condition.

The error branch receives an object with a code and a message. The author does see the remote’s own response text: the service behind that address is theirs, and its words are the diagnosis. It is never shown to the person in the chat.

Where the node will not go

Every outbound request from the platform goes through a guarded client. It resolves the hostname and refuses if the address falls into a private range: loopback, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, link-local 169.254.0.0/16 (the cloud metadata address), multicast and reserved space. Redirects are followed manually and re-checked on every hop — otherwise a public address answering 302 to http://169.254.169.254/ would bypass the check entirely.

The restriction is not cosmetic: the URL field is a template, so part of it may come from a user’s message. Without this check a chatbot becomes a scanner of the internal network of the server it runs on.

Through a proxy

The Proxy field (under advanced settings) sends the request through http://, https://, socks5:// or socks5h://. Empty means direct. The field is templated, so an address carrying a password belongs in a workspace secret and reads as {{ secret.PROXY }} rather than sitting in the graph.

The platform’s own proxy does not apply to this node: the addresses here are yours to pick, so the route is too. The private-network restrictions still hold — a proxy changes the next hop, not where the node is allowed to reach.

fetch_webpage — page reading for an agent

Fetch WebpageT
Agent extension

This node has neither a run input nor a success output: it exists only as an agent tool. Drop it on the canvas, drag tool_out into the Agent extensions port of ai_agent, and the model decides for itself when to open a link.

What it does: downloads the page, extracts the main content and converts the HTML to Markdown, dropping navigation and markup. The model gets readable text rather than a thousand-character <div>. The settings are a length limit (8000 characters by default, up to 50,000), a timeout (20 seconds by default) and a cap on the raw response size. The limit belongs to the author, not the model: the model cannot ask for more than you allowed.

Address checking is the same as for http_request: a link into the internal network is rejected, and the model is told the address is not allowed rather than handed text from an internal service.

websearch — searching the web

Web SearchT▶
QuerySearch results

The node searches the web and returns both the model’s answer and the sources themselves, with text excerpts. There is one search node on the platform and it is paid: every search is its own line in the ledger, and on top of that come the tokens of the model that writes the answer from what was found.

It attaches in two ways, and the Node mode field decides which:

  • Executable — an ordinary node: a Query input and a Search results output. You decide when to search, and the query itself arrives on the port or from the settings field.
  • As Tool — an agent extension: a link_extension wire into the Agent extensions port. Whether to search, and what to ask, is the model’s call.

How many sources to take is the Max results field: five by default, up to twenty-five. Search modes, engines, domain filters and the way the money is counted have their own page, Web search.

fetch_webpage is the natural partner: search finds the page and brings back an excerpt, fetch_webpage reads the whole thing when the excerpt is not enough. Both attach to an agent the same way, and the model picks the order itself.

Web SearchT▶
AI Agent▶▦
Fetch WebpageT
The agent searches and then reads what it found. Both attach with an extension link.
  • Extension

What next