API node
Call any external HTTP API as a workflow step, with built-in auth, templating, and SSRF protection
Purpose
The API node calls an external HTTP endpoint directly from your workflow, like a Postman request as a node. Use it to integrate any REST API that doesn't have a dedicated tool: post to a CRM, fetch a record, trigger a downstream system, or send data to a partner service.
Where the Tool node runs a governed MCP tool and the Agent node lets an LLM decide, the API node is fully deterministic: you define the request, and it runs exactly as configured every time. Every field supports template variables, so requests are built from data produced earlier in the workflow.
How it works
Workflow reaches the API node
Execution arrives at the node with the outputs of previous steps available as template variables.
Request is assembled
The URL, headers, query parameters, and body are resolved from templates. Secret references ({{vault:...}}) are pulled from HashiCorp Vault at this moment, never stored in the workflow.
Safety checks run
The target is validated against SSRF protection before the request is sent, so a templated URL can't be pointed at internal infrastructure.
Request is sent
The HTTP call is made with your configured method, auth, and timeout.
Response is captured
The status code, headers, and body are captured (JSON is parsed automatically) and made available to later nodes.
SSRF protection is always on. Requests to private, loopback, and link-local addresses are blocked so a workflow can only reach genuinely external services.
Configuration
Method and URL
Choose the HTTP method and target URL. The URL supports templates, so you can build it from earlier outputs.
Supported methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
{
"method": "POST",
"url": "https://api.example.com/users/{{input.user_id}}"
}Headers and query parameters
Add any request headers and URL query parameters. Values support templates.
{
"headers": {
"X-Trace-Id": "{{system.execution_id}}",
"Accept": "application/json"
},
"query_params": {
"include": "profile",
"verbose": "1"
}
}Request body
Set body_type to control how the body is encoded, then provide the body.
body_type | Body value | Content-Type |
|---|---|---|
json | object or array | application/json |
text | string | text/plain |
form | object | application/x-www-form-urlencoded |
multipart | object | multipart/form-data |
none | omitted | no body |
{
"body_type": "json",
"body": {
"name": "{{extract_agent.name}}",
"email": "{{extract_agent.email}}"
}
}Authentication
The API node supports six auth modes. Every secret-bearing field accepts an inline value or a Vault reference like {{vault:org/api/example}}, resolved at execution time.
No authentication.
{ "auth": { "type": "none" } }Response handling
Control timeouts, redirects, and how failures are treated.
timeout_seconds— Per-request timeout. Default 30, maximum 60.follow_redirects— Whether to follow3xxredirects. Default true.fail_on_error_status— When true, a4xx/5xxresponse fails the node so error handling can retry or branch. When false (default), the response is captured and passed on for your workflow to inspect.max_response_bytes— Caps how much of the response body is captured. Default 1 MB, maximum 16 MB.
{
"timeout_seconds": 30,
"follow_redirects": true,
"fail_on_error_status": true,
"max_response_bytes": 1048576
}Use cases
Post to a system without a dedicated tool
Scenario: Push an extracted record into an internal CRM.
Workflow:
1. Extract customer data (Agent)
2. API node: POST to CRM
3. Condition: response.status == "created"
├─ True: Send confirmation (Tool)
└─ False: Human Task: "CRM write failed, review"{
"method": "POST",
"url": "https://crm.internal.example.com/api/v2/contacts",
"body_type": "json",
"body": {
"name": "{{extract_agent.name}}",
"email": "{{extract_agent.email}}",
"source": "magoneai"
},
"auth": { "type": "bearer", "token": "{{vault:project/crm/token}}" },
"fail_on_error_status": true
}Fetch reference data for an agent
Scenario: Look up live pricing before an agent drafts a quote.
Workflow:
1. API node: GET current pricing
2. Draft quote using pricing (Agent)
3. Human Task: "Approve quote"Trigger a downstream webhook
Scenario: Notify a partner system when a workflow completes, signing the payload with HMAC.
{
"method": "POST",
"url": "https://partner.example.com/hooks/magone",
"body_type": "json",
"body": { "event": "processed", "reference": "{{input.reference}}" },
"auth": {
"type": "hmac",
"secret": "{{vault:project/partner/hmac}}",
"signed_payload": "body",
"include_timestamp": true
}
}Best practices
Use {{vault:...}} references for tokens, passwords, and secrets. They are resolved at execution time and never saved into the workflow definition or version history.
For requests that change state (POST/PUT/DELETE), set fail_on_error_status: true so a rejected request triggers retry or a fallback branch instead of silently continuing.
Set timeout_seconds to match the endpoint's expected latency. A slow third-party API shouldn't stall the whole workflow indefinitely, but don't set it so low that normal responses are cut off.
If an endpoint can return a large payload you don't need in full, lower max_response_bytes to keep only what downstream nodes will use.
When fail_on_error_status is false, use a Condition node to check the response status or body before acting on it.
Reach for the API node when no built-in tool covers the integration. If you find yourself calling the same API across many workflows, consider wrapping it as a custom MCP tool so it becomes a reusable, governed tool with managed credentials.