HTTP Request FormID 11031
Make outbound HTTP calls to any REST, SOAP, webhook, or microservice endpoint from within a BizFirst workflow. Supports all HTTP methods, dynamic expressions in every field, automatic JSON parsing, and dual output ports for 2xx and error responses.
When to Use
- External API integration: Your workflow needs live data from a third-party system — a CRM, payment gateway, ERP, or SaaS platform. The HTTP Request node lets you call any REST endpoint with dynamic headers, body, and URL path segments built from workflow expressions. No custom connector required; any service with an HTTP interface is immediately reachable.
- Webhook delivery: After completing a processing step, you need to notify a partner system, fire a downstream automation in another platform, or push a structured event payload to an external webhook URL. Configure the method as POST, compose the body from workflow variables, and optionally include an HMAC signature header computed via expressions.
- REST API CRUD operations: Your workflow manages records in an external system — creating contacts in a CRM, updating order status in an OMS, or deleting expired sessions in an identity service. Use PUT or PATCH to send targeted updates, with the resource ID interpolated directly into the URL path.
-
Internal microservice communication: In a microservices architecture, workflows may need to invoke internal service endpoints — inventory checks, pricing engines, recommendation APIs. Use custom headers (e.g.
X-Internal-Token,X-Trace-ID) for service-to-service authentication and distributed tracing correlation. - Mid-workflow data enrichment: Call an enrichment API such as an IP geolocation service, address validation API, or identity verification provider at the exact point in a workflow where the data is needed. The response is automatically parsed and available as structured fields for downstream logic.
Configuration
Request
| Field | Required | Description |
|---|---|---|
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
| Field | Required | Description |
|---|---|---|
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. |
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 Code | Cause & Resolution |
|---|---|
MISSING_URL | The 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_URL | The resolved URL is not a valid URI. Check for malformed expressions, unencoded special characters in path segments, or missing protocol scheme. |
INVALID_URL_SCHEME | The URL does not begin with http:// or https://. Other schemes (ftp, file, etc.) are not supported. |
INVALID_METHOD | The Method value is not one of the supported HTTP methods. Valid values: GET, POST, PUT, DELETE, PATCH. |
INVALID_TIMEOUT | TimeoutSeconds is outside the valid range of 1–300. The value must be a positive integer. |
INVALID_MAX_REDIRECTS | MaxRedirects 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.
| Field | Type | Description |
|---|---|---|
status | string | Always "success" on this port. |
errorCode | string | Always null on the success port. |
resource | string | Always "http". |
operation | string | Always "request". |
statusCode | integer | HTTP response status code, e.g. 200, 201, 204. |
success | boolean | Always true on this port (indicates a 2xx response). |
body | string | Raw 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_type | string | Value of the response Content-Type header, e.g. "application/json", "text/html". |
content_length | integer | Size of the response body in bytes as reported by the server. May be -1 if the server does not send a Content-Length header. |
headers | object | Dictionary of response headers. Keys are lowercase header names. Access individual headers with {{ $output.myNode.headers["x-request-id"] }}. |
parsed_json | object | If 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.
| Field | Type | Description |
|---|---|---|
status | string | Always "error" on this port. |
errorCode | string | Machine-readable error classification: HTTP_4XX, HTTP_5XX, TIMEOUT, DNS_FAILURE, TLS_ERROR, CONNECTION_REFUSED, CANCELLED, UNEXPECTED_ERROR. |
resource | string | Always "http". |
operation | string | Always "request". |
statusCode | integer | HTTP status code if the server responded (e.g. 404, 503). 0 for network-level failures where no HTTP response was received. |
message | string | Human-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.
| Expression | Returns | When to Use |
|---|---|---|
{{ $output.callApi.statusCode }} | integer | Branch on specific HTTP status codes — distinguish 200 (OK) from 201 (Created) or 204 (No Content). |
{{ $output.callApi.success }} | boolean | Quick conditional check — true for 2xx responses; use in If/Else branch to handle success vs. failure. |
{{ $output.callApi.parsed_json }} | object | Access the full parsed JSON response body as a structured object. Use when the downstream step needs multiple fields. |
{{ $output.callApi.parsed_json.id }} | string | Extract a specific field from the JSON response. Replace .id with the actual property path, including nested paths like .data.user.email. |
{{ $output.callApi.body }} | string | Access 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"] }} | string | Read a specific response header by name (always lowercase). Useful for extracting correlation IDs, rate-limit headers, or pagination cursors. |
{{ $output.callApi.content_type }} | string | Check the response content type before attempting to use parsed_json. Guard with a condition like contains(content_type, "json"). |
{{ $output.callApi.content_length }} | integer | Check payload size before processing. Alert or route differently if the response is unexpectedly large or empty (0 bytes). |
Node Policies & GuardRails
| Policy Area | Recommendation |
|---|---|
| API Key Placement | Never 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 Prevention | If 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 Tuning | The 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 Strategy | This 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 Handling | The 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 Validation | Do 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 Compliance | When 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 Awareness | Response 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. |
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.
?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