TopFlow
LearnBuildSecurity
External IntegrationP0 - Critical

HTTP Request Node

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.

Security-First Design: This node includes enterprise-grade SSRF prevention that blocks requests to private IPs, localhost, and cloud metadata endpoints. All URLs are validated before execution.

Overview

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.

Common Use Cases
1
SIEM Integration - Send security events to Splunk, Elastic, or other security platforms for centralized logging and analysis
2
Ticketing Automation - Create tickets in ServiceNow, Jira, or other ITSM platforms when security incidents are detected
3
Alerting Services - Send notifications to Slack, PagerDuty, or Microsoft Teams for critical security events
4
Threat Intelligence - Query threat intel feeds (VirusTotal, AlienVault OTX, AbuseIPDB) to enrich security analysis
5
Webhook Triggers - Trigger downstream systems when workflows complete (build deployments, approval workflows)
6
Data Enrichment - Fetch additional context from external APIs (user data, asset information, geolocation)

Configuration

Required Parameters
These fields must be configured for the node to execute
methodstring

HTTP method for the request. Options: GET, POST, PUT, PATCH, DELETE

Default: GET

urlstring

Target 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).

SSRF Protection: Blocked hosts include 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).
Optional Parameters
Additional configuration for advanced use cases
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"}

bodystring

Request body for POST/PUT/PATCH requests. Supports variable interpolation. For JSON payloads, ensure Content-Type: application/json header is set.

timeoutnumber

Request timeout in milliseconds. Default: 30000 (30 seconds). Maximum: 60000 (60 seconds).

Authentication Methods

The HTTP Request node supports multiple authentication patterns through custom headers:

Bearer Token

Most common for REST APIs. Add Authorization header with Bearer token.

{
  "Authorization": "Bearer sk-abc123..."
}
API Key (Header)

Used by many APIs. Add custom header with API key.

{
  "X-API-Key": "your-api-key-here",
  "X-Auth-Token": "token-value"
}
Basic Authentication

Legacy but still common. Encode username:password in Base64.

{
  "Authorization": "Basic dXNlcjpwYXNz"
}
Custom Authentication

Some APIs use custom schemes. Add any headers required by the API.

{
  "X-Custom-Auth": "value",
  "X-Signature": "hmac-sig"
}

Node Data Interface

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
}

Usage Examples

Example 1: Slack Webhook Notification
Send security alerts to Slack channel
Node Configuration:
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"
      }
    }
  ]
}
Expected Output:
{
  "status": 200,
  "statusText": "OK",
  "data": "ok",
  "headers": {
    "content-type": "text/plain"
  }
}
Example 2: ServiceNow Incident Creation
Create security incident ticket automatically
Node Configuration:
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"
}
Expected Output:
{
  "status": 201,
  "statusText": "Created",
  "data": {
    "result": {
      "sys_id": "abc123...",
      "number": "INC0012345",
      "state": "1",
      "short_description": "Security Incident: ..."
    }
  },
  "headers": { ... }
}
Example 3: VirusTotal IP Reputation Check
Query threat intelligence for IP address reputation
Node Configuration:
method: GET
url: https://www.virustotal.com/api/v3/ip_addresses/$input1
headers: {
  "x-apikey": "your-virustotal-api-key"
}
Expected Output:
{
  "status": 200,
  "statusText": "OK",
  "data": {
    "data": {
      "attributes": {
        "last_analysis_stats": {
          "malicious": 5,
          "suspicious": 2,
          "harmless": 80,
          "undetected": 13
        },
        "reputation": -15,
        "country": "CN"
      }
    }
  },
  "headers": { ... }
}
Example 4: Splunk HEC Event Ingestion
Send security events to Splunk via HTTP Event Collector
Node Configuration:
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"
}
Expected Output:
{
  "status": 200,
  "statusText": "OK",
  "data": {
    "text": "Success",
    "code": 0
  },
  "headers": { ... }
}
Example 5: PagerDuty Incident Trigger
Create high-priority incident for critical security events
Node Configuration:
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"
    }
  }
}
Expected Output:
{
  "status": 201,
  "statusText": "Created",
  "data": {
    "incident": {
      "id": "PXXXXXX",
      "status": "triggered",
      "html_url": "https://your-subdomain.pagerduty.com/incidents/PXXXXXX",
      "incident_number": 1234
    }
  },
  "headers": { ... }
}

Security Considerations

SSRF (Server-Side Request Forgery) Prevention: The HTTP Request node includes built-in protections against SSRF attacks, which could allow attackers to make requests to internal systems.
Blocked Protocols & Hosts
Requests to these targets will be rejected during validation
Blocked Protocols:
  • file:// - Local file system access
  • ftp:// - File transfer protocol
  • gopher:// - Legacy protocol (SSRF vector)
  • dict:// - Dictionary protocol (SSRF vector)
Blocked Hosts:
  • localhost, 127.0.0.1, 0.0.0.0 - Local system
  • 169.254.169.254 - AWS EC2 metadata endpoint
  • metadata.google.internal - GCP metadata endpoint
  • 10.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)
Known Limitation: SSRF protection validates the initial URL only. If the target URL redirects to a blocked host (e.g., http://safe.com → http://169.254.169.254), the redirect will not be blocked. Avoid requesting URLs from untrusted sources.
Best Practices for Secure API Calls
Use HTTPS for sensitive data

Always use https:// URLs when transmitting API keys, tokens, or sensitive information

Store API keys securely

Store API keys in environment variables or secure key stores. Never hardcode keys in workflow configurations exported to code repositories.

Validate SSL certificates

The HTTP Request node validates SSL certificates by default. Do not disable certificate validation in production environments.

Use rate limiting

Respect API rate limits. Add delays between requests or implement exponential backoff for high-volume workflows.

Validate response data

Always validate response data before using it in downstream nodes. Use conditional nodes to check HTTP status codes and handle errors gracefully.

Validation Rules

The HTTP Request node is validated before execution. Validation errors will block workflow execution.

Errors (Block Execution)
✕Missing required field: url
✕Empty URL value
✕Invalid URL protocol (only http:// and https:// allowed)
✕SSRF detected: URL targets blocked host (localhost, private IP, cloud metadata endpoint)
✕Invalid JSON in request body (for POST/PUT/PATCH with Content-Type: application/json)
Warnings (Don't Block)
âš Using http:// instead of https:// (insecure connection)
âš Missing Authorization header (API may reject request)
âš POST/PUT/PATCH request with body but no Content-Type header
âš Timeout value exceeds maximum (60000ms)
âš Unreferenced variable in URL or body (e.g., $input3 with only 2 upstream nodes)

Code Generation

When you export your workflow to TypeScript code, the HTTP Request node generates standard fetch() calls with proper error handling:

Generated Code (Workflow Function Export)
// 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())
}
Generated Code (Route Handler Export)
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 }
  })
}

Best Practices

Do
✓Use HTTPS for all API calls involving sensitive data or authentication tokens
✓Set appropriate timeouts based on expected API response times (default 30s is reasonable for most APIs)
✓Use Conditional nodes after HTTP Request nodes to check status codes and handle errors (e.g., retry on 429, alert on 500)
✓Validate API responses before using data in downstream nodes (check for expected fields, data types)
✓Use variable interpolation to pass dynamic data from upstream nodes ($input1, $input2)
✓Set Content-Type header when sending JSON bodies (Content-Type: application/json)
✓Test with demo mode first to verify request format before using real API keys
Don't
✕Don't hardcode API keys in URL or headers. Use environment variables or secure storage in production.
✕Don't make requests to untrusted URLs from user input without validation (SSRF risk)
✕Don't ignore HTTP status codes - Always check if request succeeded (2xx) before proceeding
✕Don't use GET requests for operations that modify data (use POST, PUT, DELETE instead)
✕Don't set extremely long timeouts (max 60s) - This can block workflow execution
✕Don't expose sensitive data in URLs (query parameters are logged) - Use request body or headers instead
✕Don't retry indefinitely on failures - Implement maximum retry limits to avoid infinite loops
Performance Tips
1
Parallel Execution

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.

2
Optimize Timeout Values

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.

3
Cache Responses

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.

4
Minimize Payload Size

Only include necessary fields in request bodies. Smaller payloads = faster transmission and processing. Use API query parameters to filter data server-side when possible.

Related Nodes

Conditional Node

Check HTTP status codes and branch workflow based on success/failure conditions.

View docs
JavaScript Node

Transform API responses, parse JSON, extract fields, or format data for downstream nodes.

View docs
Text Model Node

Analyze API responses with AI (sentiment analysis, threat classification, data extraction).

View docs
Next Steps
Workflow Patterns

Learn common workflow patterns for API integration (retry logic, error handling, parallel execution)

Integration Guide

Step-by-step guides for integrating with Splunk, ServiceNow, Slack, PagerDuty, and more

SSRF Prevention Guide

Deep dive into SSRF attack vectors and how TopFlow's validation prevents them