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