Portal Community

When to Use

Configuration

Request

FieldRequiredDescription
Url Required Full request URL including protocol scheme. Must start with http:// or https://. Path segments and query parameters can be constructed dynamically using BizFirst expressions, e.g. https://api.example.com/customers/{{ $json.customerId }}.
Method Default: GET HTTP method for the request.
GET POST PUT DELETE PATCH
Headers Optional Key-value map of HTTP request headers. Common entries: Authorization, Content-Type, Accept, X-API-Key. All values support expressions. For Bearer token auth, prefer the dedicated BearerToken field instead.
Body Optional Request body, applicable for POST, PUT, and PATCH. Can be a JSON string, a plain object expression, or a raw string. If the value is a JSON object, the node serialises it automatically and sets Content-Type: application/json if not already specified in Headers.
BearerToken Optional Shorthand for adding the Authorization: Bearer <token> header. When set, the node automatically constructs the Authorization header. If Headers also contains an Authorization entry, the explicit header takes precedence. Recommended: reference via {{ $credentials.myApiKey }}.

Behaviour

FieldRequiredDescription
TimeoutSeconds Default: 30 Maximum time in seconds to wait for a complete response. Range: 1–300. If the server does not respond within this window, the node routes to the error port with a timeout error code. For real-time user-facing flows, set to 5–10; for background batch calls to slow APIs, increase as needed.
AllowRedirects Default: true When true, the node automatically follows HTTP 301, 302, and 307 redirects. Set to false if you need to capture the redirect Location header explicitly rather than following it.
MaxRedirects Default: 10 Maximum number of redirects to follow before aborting. Range: 0–50. Only applies when AllowRedirects is true. Prevents infinite redirect loops.
NodeTypeCode: http-request — Use this identifier when referencing this node type in workflow templates, API payloads, or expression paths such as {{ $output.myNodeName.statusCode }}.

Sample Configuration

{
  "Url": "https://api.example.com/customers/{{ $json.customerId }}",
  "Method": "GET",
  "Headers": {
    "Authorization": "Bearer {{ $credentials.externalApiKey }}",
    "Accept": "application/json"
  },
  "TimeoutSeconds": 30
}

Validation Errors

Error CodeCause & Resolution
MISSING_URLThe Url field is empty or evaluates to an empty string at runtime. Ensure the URL expression resolves to a non-empty value before this node executes.
INVALID_URLThe resolved URL is not a valid URI. Check for malformed expressions, unencoded special characters in path segments, or missing protocol scheme.
INVALID_URL_SCHEMEThe URL does not begin with http:// or https://. Other schemes (ftp, file, etc.) are not supported.
INVALID_METHODThe Method value is not one of the supported HTTP methods. Valid values: GET, POST, PUT, DELETE, PATCH.
INVALID_TIMEOUTTimeoutSeconds is outside the valid range of 1–300. The value must be a positive integer.
INVALID_MAX_REDIRECTSMaxRedirects is outside the valid range of 0–50. The value must be a non-negative integer not exceeding 50.

Output

Success Port — 2xx Responses

Routes here when the server responds with a 2xx HTTP status code. All fields below are present on the success port output object.

FieldTypeDescription
statusstringAlways "success" on this port.
errorCodestringAlways null on the success port.
resourcestringAlways "http".
operationstringAlways "request".
statusCodeintegerHTTP response status code, e.g. 200, 201, 204.
successbooleanAlways true on this port (indicates a 2xx response).
bodystringRaw response body as a string. Available regardless of content type. Use this when you need the raw text or when parsed_json is null.
content_typestringValue of the response Content-Type header, e.g. "application/json", "text/html".
content_lengthintegerSize of the response body in bytes as reported by the server. May be -1 if the server does not send a Content-Length header.
headersobjectDictionary of response headers. Keys are lowercase header names. Access individual headers with {{ $output.myNode.headers["x-request-id"] }}.
parsed_jsonobjectIf the response Content-Type is application/json, this field contains the parsed JSON object. Otherwise null. Always check content_type before relying on this field.

Error Port — Non-2xx & Network Failures

Routes here for all 4xx and 5xx HTTP status codes, network errors (DNS failure, TCP timeout, TLS handshake error), and validation failures. The node does not automatically retry — implement retry logic using a TryBlock + loop pattern if needed.

FieldTypeDescription
statusstringAlways "error" on this port.
errorCodestringMachine-readable error classification: HTTP_4XX, HTTP_5XX, TIMEOUT, DNS_FAILURE, TLS_ERROR, CONNECTION_REFUSED, CANCELLED, UNEXPECTED_ERROR.
resourcestringAlways "http".
operationstringAlways "request".
statusCodeintegerHTTP status code if the server responded (e.g. 404, 503). 0 for network-level failures where no HTTP response was received.
messagestringHuman-readable error description, e.g. "Request timed out after 30s", "SSL certificate verification failed".

Sample Output

{
  "status": "success",
  "statusCode": 200,
  "success": true,
  "body": "{\"id\":\"cust-001\",\"name\":\"Acme Corp\",\"email\":\"info@acme.com\",\"plan\":\"enterprise\"}",
  "content_type": "application/json",
  "content_length": 74,
  "headers": {
    "x-ratelimit-remaining": "94",
    "x-request-id": "req_abc123"
  },
  "parsed_json": {
    "id": "cust-001",
    "name": "Acme Corp",
    "email": "info@acme.com",
    "plan": "enterprise"
  },
  "resource": "http",
  "operation": "request"
}

Expression Reference

Assuming this node is named callApi in the workflow. Replace callApi with your actual node name.

ExpressionReturnsWhen to Use
{{ $output.callApi.statusCode }}integerBranch on specific HTTP status codes — distinguish 200 (OK) from 201 (Created) or 204 (No Content).
{{ $output.callApi.success }}booleanQuick conditional check — true for 2xx responses; use in If/Else branch to handle success vs. failure.
{{ $output.callApi.parsed_json }}objectAccess the full parsed JSON response body as a structured object. Use when the downstream step needs multiple fields.
{{ $output.callApi.parsed_json.id }}stringExtract a specific field from the JSON response. Replace .id with the actual property path, including nested paths like .data.user.email.
{{ $output.callApi.body }}stringAccess the raw response body as a string — useful when the response is not JSON or when passing the raw payload to another node.
{{ $output.callApi.headers["x-request-id"] }}stringRead a specific response header by name (always lowercase). Useful for extracting correlation IDs, rate-limit headers, or pagination cursors.
{{ $output.callApi.content_type }}stringCheck the response content type before attempting to use parsed_json. Guard with a condition like contains(content_type, "json").
{{ $output.callApi.content_length }}integerCheck payload size before processing. Alert or route differently if the response is unexpectedly large or empty (0 bytes).

Node Policies & GuardRails

Policy AreaRecommendation
API Key PlacementNever embed API keys or tokens in the URL query string — they appear in server logs, browser history, and proxy logs. Always place credentials in Headers (e.g. Authorization, X-API-Key) or use the dedicated BearerToken field. Reference secrets from the Credentials Manager, not hardcoded values.
SSRF PreventionIf the URL is constructed from user-supplied input, always validate and whitelist allowed host domains before calling this node. An unrestricted URL field can be exploited to make the workflow server call internal infrastructure endpoints. Use a Code or Condition node to check the domain against an approved list.
Timeout TuningThe default 30-second timeout is a safety net, not a recommended value. For user-facing, real-time flows: set 5–10s. For background processing where a slow vendor is acceptable: 60–120s. For fire-and-forget webhooks: 10s. Always be intentional — an untuned timeout blocks a workflow execution thread.
Retry StrategyThis node does not auto-retry. For APIs subject to transient 429 (rate limit) or 503 (service unavailable) responses, implement retry logic explicitly: wrap this node in a TryBlock, use a Delay node with exponential backoff, and loop back a configurable number of times. Check statusCode on the error port to retry only on retriable status codes.
Error Port HandlingThe success port only fires on 2xx responses. All 4xx, 5xx, network errors, and timeouts route to the error port. Always connect the error port to an error-handling path — at minimum, log the errorCode and message fields. Unhandled error ports cause silent workflow failures.
Content ValidationDo not assume parsed_json is populated. It is null for non-JSON responses (HTML error pages, plain text, XML). Always guard with a content-type check before accessing parsed_json fields in downstream expressions.
Rate Limit ComplianceWhen calling an external API in a loop or batch context, add a Delay node between iterations to respect the API provider's rate limits. Consult the API documentation for rate limit headers (commonly x-ratelimit-remaining and x-ratelimit-reset) and adjust delay duration dynamically if needed.
Large Payload AwarenessResponse bodies exceeding 10 MB may cause significant memory pressure in high-concurrency workflows. If consuming a large-payload API, consider requesting paginated responses, using streaming alternatives, or processing the body incrementally in a Code node rather than passing the full object through multiple downstream steps.
SSRF Risk: If Url is built from user-provided input without validation, an attacker can route workflow HTTP calls to internal services (e.g. http://169.254.169.254/ for cloud metadata). Always validate and whitelist the target domain before executing this node when URL is user-influenced.
Secrets in URLs: Never include API keys, tokens, or passwords as URL query parameters (e.g. ?api_key=secret). Use the Headers or BearerToken fields and store credentials in the BizFirst Credentials Manager.

Workflow Examples

Example 1 — Fetch Customer from CRM (GET with Bearer Auth)

Retrieve a customer record from an external CRM API using a dynamic customer ID from the workflow context. The Authorization header is supplied from the Credentials Manager.

{
  "nodeType": "http-request",
  "name": "fetchCustomer",
  "Url": "https://api.crm.example.com/v2/customers/{{ $json.customerId }}",
  "Method": "GET",
  "Headers": {
    "Authorization": "Bearer {{ $credentials.crmApiToken }}",
    "Accept": "application/json"
  },
  "TimeoutSeconds": 15
}

// Downstream expression to read the plan tier:
// {{ $output.fetchCustomer.parsed_json.subscription.plan }}

Example 2 — POST Webhook with JSON Body

Deliver a structured event notification to a partner system's webhook endpoint after completing a fulfilment step. The payload is assembled from multiple workflow variables.

{
  "nodeType": "http-request",
  "name": "notifyPartner",
  "Url": "https://hooks.partner.example.com/events/fulfilment",
  "Method": "POST",
  "Headers": {
    "Content-Type": "application/json",
    "X-API-Key": "{{ $credentials.partnerWebhookKey }}",
    "X-Trace-ID": "{{ $context.workflowRunId }}"
  },
  "Body": {
    "event": "order.fulfilled",
    "orderId": "{{ $json.orderId }}",
    "fulfilledAt": "{{ $now }}",
    "trackingNumber": "{{ $json.tracking.number }}",
    "carrier": "{{ $json.tracking.carrier }}"
  },
  "TimeoutSeconds": 10
}

Example 3 — PATCH Update with Error Handling

Update a record status in an external order management system. The error port connects to an alert node that notifies the operations team on failure.

{
  "nodeType": "http-request",
  "name": "updateOrderStatus",
  "Url": "https://oms.example.com/api/orders/{{ $json.orderId }}",
  "Method": "PATCH",
  "Headers": {
    "Authorization": "Bearer {{ $credentials.omsToken }}",
    "Content-Type": "application/json"
  },
  "Body": {
    "status": "{{ $json.newStatus }}",
    "updatedBy": "{{ $context.triggeredBy }}",
    "note": "Automated update via BizFirst workflow"
  },
  "TimeoutSeconds": 20
}

// On error port — check what went wrong:
// {{ $output.updateOrderStatus.statusCode }}  → e.g. 409 (conflict)
// {{ $output.updateOrderStatus.errorCode }}   → e.g. "HTTP_4XX"
// {{ $output.updateOrderStatus.message }}     → human-readable description

Example 4 — Data Enrichment: IP Geolocation Mid-Workflow

Look up the geographic location of a user's IP address mid-workflow to personalise content or flag suspicious access attempts. Uses a public API with a simple GET call.

{
  "nodeType": "http-request",
  "name": "geoLookup",
  "Url": "https://ipapi.example.com/json/{{ $json.userIpAddress }}",
  "Method": "GET",
  "Headers": {
    "X-API-Key": "{{ $credentials.geoApiKey }}"
  },
  "TimeoutSeconds": 8
}

// Downstream expressions:
// {{ $output.geoLookup.parsed_json.country_code }}  → "US"
// {{ $output.geoLookup.parsed_json.city }}          → "New York"
// {{ $output.geoLookup.parsed_json.is_vpn }}        → false