Docs / Strand / nodes/http-request

HTTP Request Node

The HTTP Request node makes HTTP requests to external APIs.

The HTTP Request node's Configuration: method, URL, headers, and body. Any field here accepts Jinja, so {{ vault.api_token }} in a header keeps the secret out of the node.

Overview

HTTP Request nodes allow you to call external APIs, webhooks, and HTTP endpoints from your workflows.

Use Cases
  • Call REST APIs
  • Send webhooks
  • Fetch data from external services
  • Integrate with third-party services

Configuration

Field Type Required Description
url string Yes* Full request URL (supports templating)
endpoint string No Path appended to connector base URL
method string No HTTP method (default: POST)
headers object No Request headers (values support templating)
body string/object No Request body (supports templating)
body_type string No Body format: json, form_data, form_urlencoded, raw, xml, binary (default: json)
query_params object No URL query parameters (supports templating)
path_params object No URL path parameter replacements
connector_id string No Use a saved HTTP connector
timeout number No Request timeout in seconds, 1-300 (default: 30)
follow_redirects boolean No Follow HTTP redirects (default: true)
verify_ssl boolean No Verify SSL certificates (default: true)
retry object No Retry configuration (see below)
URL vs Connector
  • Use url for direct API calls
  • Use connector_id + endpoint for saved connectors with authentication

URL Configuration

Direct URL

jinja

https://api.example.com/users/{{ payload.user_id }}

Using Connector

When using a connector, specify the endpoint instead of full URL:

jinja

/users/{{ payload.user_id }}/profile

The connector provides the base URL and authentication.

HTTP Methods

Method Use Case Body Required?
GET Retrieve data No
POST Create resources Usually
PUT Update resources Usually
PATCH Partial updates Usually
DELETE Delete resources No

Headers

Headers support templating in their values:

json

{
  "Authorization": "Bearer {{ vault.api_token }}",
  "Content-Type": "application/json",
  "X-User-ID": "{{ payload.user_id }}"
}
Sensitive Headers

For sensitive values like API tokens, use the Global Vault instead of Workflow Variables. Headers are also automatically encrypted when using connectors.

Request Body

JSON Body

json

{
  "user_id": "{{ steps.user_lookup.output_payload.id }}",
  "message": "{{ payload.message }}",
  "timestamp": "{{ meta.received_at }}"
}

String Body

jinja

{{ payload | tojson }}

Using Previous Steps (Direct Connection)

When directly connected, use payload:

json

{
  "data": {{ payload | tojson }},
  "metadata": {
    "source": "{{ initial.meta.trigger_source }}"
  }
}

Using Non-Direct Steps

When accessing data from a non-directly connected node:

json

{
  "data": {{ steps.process.output_payload | tojson }},
  "metadata": {
    "source": "{{ initial.meta.trigger_source }}"
  }
}

Query Parameters

Add query parameters to the URL:

json

{
  "page": "{{ payload.page | default(1) }}",
  "limit": "50",
  "filter": "{{ payload.status }}"
}

Results in: ?page=1&limit=50&filter=active

Path Parameters

Replace placeholders in the URL with dynamic values:

json

  {
    "user_id": "{{ payload.user_id }}",
    "order_id": "{{ payload.order_id }}"
  }

Body Types

The body_type field controls how the request body is formatted:

Body Type Content-Type Use Case
json application/json REST APIs (default)
form_urlencoded application/x-www-form-urlencoded Form submissions
form_data multipart/form-data File uploads
raw Custom Raw text or custom formats
xml application/xml SOAP/XML APIs

Retry Configuration

Configure automatic retries for transient failures:

json

{
  "retry": {
    "enabled": true,
    "max_attempts": 3,
    "backoff_type": "exponential",
    "backoff_delay": 1,
    "backoff_max": 30,
    "retryable_status_codes": [429, 500, 502, 503, 504]
  }
}
Field Type Description
enabled boolean Enable retries
max_attempts number Max retry attempts, 1-10 (default: 3)
backoff_type string exponential, linear, or fixed
backoff_delay number Initial delay between retries in seconds
backoff_max number Maximum delay between retries in seconds
retryable_status_codes array HTTP status codes that trigger a retry

Response

The HTTP Request node outputs:

Accessing Response

jinja

{{ steps.api_call.output_payload.data }}
{{ steps.api_call.output_meta.status_code }}

Error Handling

HTTP errors (4xx, 5xx) are treated as node failures. A failed node is logged and marked failed, and its downstream edges are not traversed. There is no "on error" route, so that branch simply stops.

To branch on the result instead of halting, call the API through a saved HTTP connector. Connectors return a { success, status, data } envelope (see Connector Output Structure) rather than raising, so you can route on it with an If/Else Logic node:

jinja

{{ payload.success }}

The if handle handles success; the else handle handles failure. See Conditional Logic.

Examples

GET Request

Configuration:

POST Request with Body (Direct Connection)

Configuration:

json

  {
    "to": "{{ payload.email }}",
    "subject": "Welcome!",
    "body": "Hello {{ payload.name }}"
  }
Direct Connection

Since this HTTP Request node is directly connected to the previous node, use payload instead of steps.node_id.output_payload.

Using Connector

Configuration:

The connector provides base URL and authentication automatically.

Best Practices

Tips
  1. Use connectors for APIs requiring authentication
  2. Store API tokens in the Global Vault, not hardcoded or in Workflow Variables
  3. Use templating for dynamic URLs and data
  4. To branch on failures, call through a connector and route on {{ payload.success }} with a Logic node; a raw HTTP node failure halts that branch
  5. Check response status codes in conditions
  6. Test with sample data before deploying