Documentation Index
Fetch the complete documentation index at: https://docs.dualship.run/llms.txt
Use this file to discover all available pages before exploring further.
The http node makes HTTP requests to external APIs. It supports all standard HTTP methods, custom headers, query parameters, and request bodies.
Configuration
{
"id": "fetch_user",
"type": "http",
"config": {
"method": "GET",
"url": "https://api.example.com/users/{{user_id}}",
"headers": {
"Authorization": "Bearer {{env.API_KEY}}"
},
"timeout": 10000
}
}
Config Fields
| Field | Type | Required | Default | Description |
|---|
url | string | Yes | - | Request URL (supports templates) |
method | string | No | "GET" | HTTP method |
headers | object | No | - | Request headers |
query | object | No | - | Query string parameters |
body | any | No | - | Request body |
body_type | string | No | "json" | Body format: "json", "form", or "multipart" |
files | array | No | - | Files to upload (auto-sets body_type to multipart) |
timeout | number | No | 30000 | Timeout in milliseconds (max 60000) |
content_type | string | No | auto | Content-Type header |
on_error | string | No | "abort" | Error handling: "abort" or "continue" |
HTTP Methods
Supported methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS
{ "method": "GET" }
{ "method": "POST" }
{ "method": "PUT" }
{ "method": "DELETE" }
{ "method": "PATCH" }
Output
{
"status_code": 200,
"headers": {
"content-type": "application/json",
"x-request-id": "abc123"
},
"body": {
"id": 1,
"name": "John Doe"
},
"latency_ms": 150,
"success": true,
"error": null
}
| Field | Type | Description |
|---|
status_code | number | HTTP status code |
headers | object | Response headers |
body | any | Response body (auto-parsed if JSON) |
latency_ms | number | Request duration in milliseconds |
success | boolean | true if status is 2xx |
error | string | Error message (only with on_error: "continue") |
Examples
GET Request
{
"id": "get_user",
"type": "http",
"config": {
"method": "GET",
"url": "https://api.example.com/users/{{request.query.user_id}}"
}
}
GET with Query Parameters
{
"id": "search_users",
"type": "http",
"config": {
"method": "GET",
"url": "https://api.example.com/users",
"query": {
"search": "{{request.query.q}}",
"limit": "10",
"offset": "{{request.query.page | multiply:10}}"
}
}
}
POST with JSON Body
{
"id": "create_user",
"type": "http",
"config": {
"method": "POST",
"url": "https://api.example.com/users",
"headers": {
"Authorization": "Bearer {{env.API_KEY}}",
"Content-Type": "application/json"
},
"body": {
"name": "{{request.body.name}}",
"email": "{{request.body.email}}",
"role": "user"
}
}
}
PUT Request
{
"id": "update_user",
"type": "http",
"config": {
"method": "PUT",
"url": "https://api.example.com/users/{{user_id}}",
"body": {
"name": "{{request.body.name}}",
"updated_at": "{{now}}"
}
}
}
DELETE Request
{
"id": "delete_user",
"type": "http",
"config": {
"method": "DELETE",
"url": "https://api.example.com/users/{{request.body.user_id}}"
}
}
{
"id": "api_call",
"type": "http",
"config": {
"method": "POST",
"url": "https://api.example.com/webhook",
"headers": {
"Authorization": "Bearer {{env.API_TOKEN}}",
"X-Request-ID": "{{request_id}}",
"X-Timestamp": "{{now}}",
"Accept": "application/json"
},
"body": "{{payload}}"
}
}
With Timeout
{
"id": "slow_api",
"type": "http",
"config": {
"url": "https://slow-api.example.com/process",
"timeout": 60000
}
}
Error Handling
on_error: "abort" (default)
If the request fails (network error, timeout, non-2xx status), the flow stops immediately.
{
"id": "critical_api",
"type": "http",
"config": {
"url": "https://api.example.com/critical",
"on_error": "abort"
}
}
on_error: "continue"
Errors are captured in the output instead of failing the flow:
{
"id": "optional_api",
"type": "http",
"config": {
"url": "https://api.example.com/optional",
"on_error": "continue"
}
}
Then check the result:
{
"id": "check_result",
"type": "condition",
"config": {
"conditions": [
{
"if": "{{optional_api.output.success}} == true",
"then": ["process_data"]
}
],
"else": ["use_fallback"]
}
}
Body Handling
JSON Body (default)
Objects are automatically serialized as JSON:
{
"body": {
"name": "John",
"age": 30
}
}
Use body_type: "form" to send application/x-www-form-urlencoded data. Common for OAuth token requests:
{
"id": "oauth_token",
"type": "http",
"config": {
"method": "POST",
"url": "https://oauth.example.com/token",
"body_type": "form",
"body": {
"grant_type": "client_credentials",
"client_id": "{{env.CLIENT_ID}}",
"client_secret": "{{env.CLIENT_SECRET}}"
}
}
}
The body is encoded as: grant_type=client_credentials&client_id=xxx&client_secret=yyy
Multipart File Upload
Use body_type: "multipart" or add a files array to upload files:
{
"id": "upload_file",
"type": "http",
"config": {
"method": "POST",
"url": "https://api.example.com/upload",
"body": {
"description": "Monthly report",
"category": "reports"
},
"files": [
{
"field": "document",
"filename": "report.pdf",
"content": "base64:JVBERi0xLjQK..."
}
]
}
}
File Config:
| Field | Type | Required | Description |
|---|
field | string | Yes | Form field name for the file |
filename | string | Yes | Filename to send |
content | string | Yes | File content (prefix with base64: for binary) |
Multiple Files:
{
"files": [
{
"field": "document",
"filename": "report.pdf",
"content": "base64:JVBERi0xLjQK..."
},
{
"field": "thumbnail",
"filename": "preview.png",
"content": "base64:iVBORw0KGgo..."
}
]
}
String Body
Strings are sent as-is:
{
"body": "raw string content",
"content_type": "text/plain"
}
Template Body
Use templates for dynamic content:
{
"body": "{{prepared_payload}}"
}
Response Parsing
- JSON responses are automatically parsed into objects
- Other responses are returned as strings
- Check
Content-Type header to determine response format
URL Templates
The URL supports template expressions:
"url": "https://api.example.com/users/{{user_id}}/posts/{{post_id}}" # Path parameters
"url": "https://{{env.API_HOST}}/v1/users" # Dynamic host
"url": "https://api.example.com/{{api_version}}/users" # Conditional path
Common Patterns
Authenticated Request
{
"id": "authenticated_call",
"type": "http",
"config": {
"url": "https://api.example.com/protected",
"headers": {
"Authorization": "Bearer {{auth_token}}"
}
}
}
OAuth Token Exchange
{
"id": "get_token",
"type": "http",
"config": {
"method": "POST",
"url": "https://oauth.example.com/token",
"body_type": "form",
"body": {
"grant_type": "client_credentials",
"client_id": "{{env.CLIENT_ID}}",
"client_secret": "{{env.CLIENT_SECRET}}",
"scope": "read write"
}
}
}
Then use the token in subsequent requests:
{
"id": "api_call",
"type": "http",
"config": {
"url": "https://api.example.com/data",
"headers": {
"Authorization": "Bearer {{get_token.output.body.access_token}}"
}
}
}
{
"id": "fetch_page",
"type": "http",
"config": {
"url": "https://api.example.com/items",
"query": {
"page": "{{current_page}}",
"per_page": "50"
}
}
}
Webhook Call
{
"id": "send_webhook",
"type": "http",
"config": {
"method": "POST",
"url": "{{webhook_url}}",
"headers": {
"X-Webhook-Secret": "{{env.WEBHOOK_SECRET}}"
},
"body": {
"event": "order.created",
"data": "{{order}}"
}
}
}
File Upload
{
"id": "upload_document",
"type": "http",
"config": {
"method": "POST",
"url": "https://api.example.com/documents",
"headers": {
"Authorization": "Bearer {{env.API_KEY}}"
},
"body": {
"title": "{{request.body.title}}",
"folder_id": "{{request.body.folder_id}}"
},
"files": [
{
"field": "file",
"filename": "{{request.body.filename}}",
"content": "{{request.body.file_content}}"
}
]
}
}