Return

Returns a value from the current workflow. In simple mode, it passes the input through as-is with HTTP status 200. In custom mode, you can shape the response body with a template and set a custom status code.

When to Use

Use Return:

  • At the end of an API Endpoint workflow with responseMode: use-workflow-response — the returned value becomes the HTTP response body and status code
  • At the end of a Webhook workflow with responseMode: use-workflow-response — same synchronous response behavior
  • At the end of any workflow called as a subworkflow — the returned value becomes the result output of the Subworkflow node in the parent

You do not need Return in webhook workflows using the default ack-immediately response mode.

Inputs

HandleTypeDescription
inputanyThe value to return. Connect any upstream node's output here. Required.

Outputs

None. Return is a terminal node — it ends the execution path and passes the value to the caller.

Settings

Return Mode

SettingTypeDefaultDescription
returnModeselectsimpleChoose simple to pass input through unchanged (status 200), or custom to shape the response body and set a custom status code.

Custom Mode Settings

These fields appear only when returnMode is set to custom:

SettingTypeDefaultDescription
statusCodetext200HTTP status code for the response (e.g. 200, 400, 404).
modeselectobjectBody shaping strategy. object builds a JSON body from a template. expression evaluates a single expression or nested structure.
templatecode editorShape the response body using {{ }} bindings. Supports template expressions. If left empty, input is passed through unchanged with the configured status code.

Template Presets

When in custom mode, the template field offers three quick-start presets:

| Preset | Status | Template | |--------|--------|----------| | REST Success | 200 | {"success": true, "data": "{{ input }}", "message": ""} | | REST Error | 400 | {"success": false, "error": {"code": "UNKNOWN_ERROR", "message": "{{ input }}"}} | | Webhook Ack | 200 | {"received": true, "status": "ok"} |

Clicking a preset fills the template and sets the status code automatically.

Simple vs Custom Mode

Simple mode is the default. It passes the connected input value through unchanged and always returns HTTP status 200. Use this when you just need to forward an upstream node's output to the caller without transformation.

Custom mode gives you full control over the HTTP response:

  • Set the status code to any valid HTTP status (200, 201, 400, 404, 500, etc.)
  • Shape the response body using a JSON template with {{ }} bindings
  • Choose between object mode (JSON template) and expression mode (single expression)

Object Mode

Write a JSON template in the code editor. Use {{ }} bindings to inject values:

{
  "success": true,
  "user": {
    "id": "{{ http_request.data.id }}",
    "email": "{{ http_request.data.email }}"
  },
  "timestamp": "{{ input.created_at }}"
}

Bindings inside quoted strings are resolved as strings. Unquoted bindings like {{ input }} are resolved to their native type (object, array, number, etc.).

Expression Mode

Evaluate a single expression that returns the entire response body:

{{ input }}

Or build a value using workflow variables:

{{ {"users": http_request.data, "count": len(http_request.data)} }}

Error Handling

Return has a hidden On Error control output branch. Enable it via the "Error output handle" toggle at the bottom of the settings panel.

The error branch fires when:

  • A JSON template produces invalid JSON after binding resolution (object mode)
  • An expression fails to evaluate
  • Any runtime exception occurs during template processing

Connect the error output to a fallback Return node or a notification action to handle failures gracefully.

Example

Canvas

API Endpoint workflow returning a shaped JSON response with a custom status code:

API Endpoint (POST /users/:id) → HTTP Request (fetch user) → Return (custom, 200)

Return settings:

  • Return Mode: custom
  • Status Code: 200
  • Mode: object
  • Template:
{
  "success": true,
  "data": {
    "id": "{{ http_request.data.id }}",
    "email": "{{ http_request.data.email }}",
    "plan": "{{ http_request.data.plan }}"
  }
}

The caller receives this JSON as the HTTP response body with status 200.

Subworkflow with branching return values:

Manual Trigger → HTTP Request (validate ID) → If ({{ http_request.status }} == 200)
    → true:  Return (simple — forwards http_request.data)
    → false: Return (custom, 404 — {"error": "User not found"})

The parent workflow accesses the result via {{ subworkflow.result }}.

TSL

import api_trigger from @tensorify/api-trigger:1.0.0
import http_request from @tensorify/http-request:3.0.0
import return_node from @tensorify/return:3.0.0

node api @tensorify/api-trigger:1.0.0 {
    path = "/users"
    method = "POST"
    responseMode = "use-workflow-response"
}

node fetch @tensorify/http-request:3.0.0 {
    method = "GET"
    url = "https://api.example.com/users/{{ api.body.id }}"
}

node respond @tensorify/return:3.0.0 {
    returnMode = "custom"
    statusCode = "200"
    mode = "object"
}

api.payload -> fetch.body
fetch.response -> respond.input

Cross-Plugin Behavior

With API Endpoint and Webhook Trigger

When the trigger is configured with responseMode: use-workflow-response, the HTTP connection stays open until a Return node fires. Return's result becomes the HTTP response body and statusCode becomes the HTTP response status.

If no Return node fires before the timeout, the caller receives a 504 Gateway Timeout.

In the default ack-immediately mode, the trigger responds with {"status": "success", "requestId": "..."} instantly — Return nodes are ignored for the HTTP response.

With Subworkflow

When a workflow is called as a subworkflow, the Return node's result value becomes the result output of the Subworkflow node in the parent workflow. Access it as {{ subworkflow.result }}.

Important: Only the body propagates across the subworkflow boundary. The statusCode is not passed to the parent — it is only relevant for HTTP responses. If the child workflow does not reach a Return node, the parent receives null.

Common Gotchas

  • Simple mode always returns 200: Even if statusCode was previously configured in custom mode, switching to simple mode ignores it and always returns HTTP 200.
  • Multiple Return nodes: You can have more than one Return node (e.g., one on each branch of an If node). The first Return that executes ends the workflow.
  • Subworkflow status codes: Custom status codes only affect HTTP responses (API Endpoint / Webhook). In subworkflow calls, only the body value is returned — the status code is discarded.
  • Empty template in custom mode: If the template field is left empty, the input is passed through unchanged (same as simple mode) but with the configured status code.
  • Timeout: If responseMode is use-workflow-response and no Return node fires before the timeout, the caller's connection is dropped with a timeout error.

See Also

On this page