Make external API calls to integrate with SIEM systems, ticketing platforms, alerting services, and any REST API. Built-in SSRF prevention ensures secure external communication.
The HTTP Request node enables your workflows to communicate with external APIs and services. It supports all standard HTTP methods (GET, POST, PUT, PATCH, DELETE), custom headers, request bodies, and multiple authentication patterns.
methodstringHTTP method for the request. Options: GET, POST, PUT, PATCH, DELETE
Default: GET
urlstringTarget URL for the HTTP request. Supports variable interpolation ($input1, $input2).
Security: Only http:// and https:// protocols allowed. Requests to private IPs, localhost, and cloud metadata endpoints are blocked (SSRF prevention).
localhost, 127.0.0.1, 169.254.169.254 (AWS metadata), metadata.google.internal (GCP), and all private IP ranges (10.x, 172.16.x, 192.168.x).headersRecord<string, string>Custom HTTP headers as key-value pairs. Common uses: authentication tokens, content types, custom API headers.
Example: {"Authorization": "Bearer $token", "Content-Type": "application/json"}
bodystringRequest body for POST/PUT/PATCH requests. Supports variable interpolation. For JSON payloads, ensure Content-Type: application/json header is set.
timeoutnumberRequest timeout in milliseconds. Default: 30000 (30 seconds). Maximum: 60000 (60 seconds).
The HTTP Request node supports multiple authentication patterns through custom headers:
Most common for REST APIs. Add Authorization header with Bearer token.
{
"Authorization": "Bearer sk-abc123..."
}Used by many APIs. Add custom header with API key.
{
"X-API-Key": "your-api-key-here",
"X-Auth-Token": "token-value"
}Legacy but still common. Encode username:password in Base64.
{
"Authorization": "Basic dXNlcjpwYXNz"
}Some APIs use custom schemes. Add any headers required by the API.
{
"X-Custom-Auth": "value",
"X-Signature": "hmac-sig"
}TypeScript interface defining the HTTP Request node's configuration and execution state:
export type HttpRequestNodeData = {
// Configuration
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE"
url: string
headers?: Record<string, string>
body?: string
timeout?: number // milliseconds, default: 30000, max: 60000
// Execution state (managed by system)
status?: "idle" | "running" | "completed" | "error"
output?: {
status: number // HTTP status code (200, 404, 500, etc.)
statusText: string // Status message
data: any // Response body (parsed JSON or raw text)
headers: Record<string, string> // Response headers
}
error?: string
}method: POST
url: https://hooks.slack.com/services/YOUR/WEBHOOK/URL
headers: {
"Content-Type": "application/json"
}
body: {
"text": "🚨 Security Alert: $input1",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Security Event Detected*\n$input1"
}
}
]
}{
"status": 200,
"statusText": "OK",
"data": "ok",
"headers": {
"content-type": "text/plain"
}
}method: POST
url: https://your-instance.service-now.com/api/now/table/incident
headers: {
"Authorization": "Basic YOUR_BASE64_CREDENTIALS",
"Content-Type": "application/json",
"Accept": "application/json"
}
body: {
"short_description": "Security Incident: $input1",
"description": "$input2",
"urgency": "1",
"impact": "1",
"category": "Security",
"subcategory": "Security Incident"
}{
"status": 201,
"statusText": "Created",
"data": {
"result": {
"sys_id": "abc123...",
"number": "INC0012345",
"state": "1",
"short_description": "Security Incident: ..."
}
},
"headers": { ... }
}method: GET
url: https://www.virustotal.com/api/v3/ip_addresses/$input1
headers: {
"x-apikey": "your-virustotal-api-key"
}{
"status": 200,
"statusText": "OK",
"data": {
"data": {
"attributes": {
"last_analysis_stats": {
"malicious": 5,
"suspicious": 2,
"harmless": 80,
"undetected": 13
},
"reputation": -15,
"country": "CN"
}
}
},
"headers": { ... }
}method: POST
url: https://splunk.example.com:8088/services/collector/event
headers: {
"Authorization": "Splunk YOUR-HEC-TOKEN",
"Content-Type": "application/json"
}
body: {
"event": {
"severity": "high",
"source_ip": "$input1",
"event_type": "security_alert",
"description": "$input2",
"timestamp": "2026-01-11T18:15:25.839Z"
},
"sourcetype": "_json",
"index": "security"
}{
"status": 200,
"statusText": "OK",
"data": {
"text": "Success",
"code": 0
},
"headers": { ... }
}method: POST
url: https://api.pagerduty.com/incidents
headers: {
"Authorization": "Token token=YOUR_API_TOKEN",
"Content-Type": "application/json",
"Accept": "application/vnd.pagerduty+json;version=2",
"From": "security@example.com"
}
body: {
"incident": {
"type": "incident",
"title": "Security Alert: $input1",
"service": {
"id": "YOUR_SERVICE_ID",
"type": "service_reference"
},
"urgency": "high",
"body": {
"type": "incident_body",
"details": "$input2"
}
}
}{
"status": 201,
"statusText": "Created",
"data": {
"incident": {
"id": "PXXXXXX",
"status": "triggered",
"html_url": "https://your-subdomain.pagerduty.com/incidents/PXXXXXX",
"incident_number": 1234
}
},
"headers": { ... }
}file:// - Local file system accessftp:// - File transfer protocolgopher:// - Legacy protocol (SSRF vector)dict:// - Dictionary protocol (SSRF vector)localhost, 127.0.0.1, 0.0.0.0 - Local system169.254.169.254 - AWS EC2 metadata endpointmetadata.google.internal - GCP metadata endpoint10.x.x.x - Private IP range (Class A)172.16.x.x - 172.31.x.x - Private IP range (Class B)192.168.x.x - Private IP range (Class C)http://safe.com → http://169.254.169.254), the redirect will not be blocked. Avoid requesting URLs from untrusted sources.Always use https:// URLs when transmitting API keys, tokens, or sensitive information
Store API keys in environment variables or secure key stores. Never hardcode keys in workflow configurations exported to code repositories.
The HTTP Request node validates SSL certificates by default. Do not disable certificate validation in production environments.
Respect API rate limits. Add delays between requests or implement exponential backoff for high-volume workflows.
Always validate response data before using it in downstream nodes. Use conditional nodes to check HTTP status codes and handle errors gracefully.
The HTTP Request node is validated before execution. Validation errors will block workflow execution.
urlhttp:// and https:// allowed)http:// instead of https:// (insecure connection)Content-Type headerWhen you export your workflow to TypeScript code, the HTTP Request node generates standard fetch() calls with proper error handling:
// HTTP Request Node: Send alert to Slack
const node_httpRequest1 = await fetch("https://hooks.slack.com/services/YOUR/WEBHOOK/URL", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
text: `🚨 Security Alert: ${node_textModel1}`,
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: `*Security Event Detected*\n${node_textModel1}`
}
}
]
}),
signal: AbortSignal.timeout(30000) // 30s timeout
})
if (!node_httpRequest1.ok) {
throw new Error(`HTTP Request failed: ${node_httpRequest1.status} ${node_httpRequest1.statusText}`)
}
const httpRequest1_data = await node_httpRequest1.json()
const httpRequest1_result = {
status: node_httpRequest1.status,
statusText: node_httpRequest1.statusText,
data: httpRequest1_data,
headers: Object.fromEntries(node_httpRequest1.headers.entries())
}export async function POST(req: Request) {
// ... previous nodes ...
// HTTP Request Node: Send alert to Slack
const node_httpRequest1 = await fetch(
"https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
{
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
text: `🚨 Security Alert: ${node_textModel1}`,
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: `*Security Event Detected*\n${node_textModel1}`
}
}
]
}),
signal: AbortSignal.timeout(30000)
}
)
if (!node_httpRequest1.ok) {
return Response.json(
{ error: `HTTP Request failed: ${node_httpRequest1.status}` },
{ status: 500 }
)
}
const httpRequest1_result = {
status: node_httpRequest1.status,
statusText: node_httpRequest1.statusText,
data: await node_httpRequest1.json(),
headers: Object.fromEntries(node_httpRequest1.headers.entries())
}
// ... downstream nodes ...
return Response.json({
success: true,
outputs: { httpRequest1: httpRequest1_result }
})
}When making multiple independent API calls, connect them in parallel (not sequential) to reduce total execution time. TopFlow's topological execution will run them concurrently.
Set shorter timeouts for fast APIs (5-10s) and longer timeouts for slow APIs (30-60s). This prevents workflows from waiting unnecessarily on slow or failing APIs.
For data that doesn't change frequently (threat intel scores, asset info), consider implementing caching in your exported code to reduce API calls and improve performance.
Only include necessary fields in request bodies. Smaller payloads = faster transmission and processing. Use API query parameters to filter data server-side when possible.
Learn common workflow patterns for API integration (retry logic, error handling, parallel execution)
Step-by-step guides for integrating with Splunk, ServiceNow, Slack, PagerDuty, and more
Deep dive into SSRF attack vectors and how TopFlow's validation prevents them