Custom Actions

Call any REST API not in the built-in app catalog. Configure URL, method, headers, and body template β€” then use the response like any other step output.


What are Custom Actions?

Custom Actions are HTTP Request steps backed by the http-request app. They let you call any REST API β€” internal tools, proprietary data sources, third-party services without a native integration β€” without writing code.

The URL, headers, and body are templates. You can inject previous step outputs, input fields, or workspace secrets using the standard {{variable}} syntax.


Configuration

{
  type: "appAction",
  app: { id: "http-request", actionId: "request" },
  stepInputData: {
    url: "https://api.example.com/enrich?domain={{input.domain}}",
    method: "GET",           // GET | POST | PUT | DELETE | PATCH
    headers: {
      "Authorization": "Bearer {{input.apiKey}}",
      "Content-Type": "application/json"
    },
    body: {                  // for POST / PUT / PATCH
      "company": "{{steps.enrich.name}}",
      "score": "{{steps.score.value}}"
    }
  }
}

url β€” supports template variables; query params can be baked in or built dynamically.

headers β€” JSON object; use for auth tokens, content type, custom headers.

body β€” JSON object or string template; used with POST / PUT / PATCH.


Input & Output

Inputs are template variables resolved at execution time from workflow inputs and previous step outputs. The HTTP response is automatically parsed:

  • β€’JSON response β€” parsed into an object; fields are available as {{steps.my_step.fieldName}} in downstream steps.
  • β€’Text / HTML response β€” available as {{steps.my_step.body}}.
  • β€’Status code β€” available as {{steps.my_step.status}} for conditional routing.

Testing Before Adding to a Workflow

Use test_app_action from any MCP client to fire a live request and inspect the response without consuming workflow credits or creating an execution:

test_app_action("http-request", "request", {
  url: "https://api.example.com/companies/acme",
  method: "GET",
  headers: { "Authorization": "Bearer sk-..." }
})
// Returns the live response so you can inspect fields before wiring them up

Authentication Patterns

Bearer Token in Header

headers: { "Authorization": "Bearer {{input.token}}" }

API Key as Query Param

url: "https://api.example.com/data?api_key={{input.apiKey}}"

Basic Auth

headers: { "Authorization": "Basic {{input.base64Credentials}}" }

Avoid hardcoding secrets in step config. Pass them as workflow inputs (marked sensitive) or retrieve from workspace secrets if supported.


Example: Call an Internal Webhook

{
  type: "appAction",
  app: { id: "http-request", actionId: "request" },
  stepInputData: {
    url: "https://hooks.company.internal/deal-scored",
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: {
      "dealId": "{{input.dealId}}",
      "score": "{{steps.score.value}}",
      "tier": "{{steps.aggregate.tier}}"
    }
  }
}

Next Steps

  • App System β€” Browse 100+ built-in integrations before building a custom action
  • App Actions Reference β€” Input / output schemas for all native actions
  • n8n Import β€” Import HTTP Request nodes from existing n8n workflows