logo_smallAxellero.io

End

Workflow execution exit point that defines output parameters and HTTP responses.

The End node terminates workflow execution and defines the response structure returned to the calling system. It handles output formatting, HTTP response configuration, and error handling for completed workflows.

┌─────────────────────────────────────────────────────────┐
│                   WORKFLOW COMPLETION                   │
├─────────────────────────────────────────────────────────┤
│                                                         │
│    ┌─────────┐     ┌─────────┐     ┌─────────┐          │
│    │ PROCESS │────▶│  LOGIC  │────▶│   END   │          │
│    │  NODES  │     │  NODES  │     │  NODE   │          │
│    └─────────┘     └─────────┘     └─────────┘          │
│         │               │               │               │
│    Data Processing   Business Logic  Response           │
│         │               │               │               │
│         └───── Workflow Execution ──────┘               │
│                                         │               │
│                                   ┌─────▼─────┐         │
│                                   │  CALLER   │         │
│                                   │ RESPONSE  │         │
│                                   └───────────┘         │
│                                                         │
└─────────────────────────────────────────────────────────┘

Configuration (Readonly)

PropertyValue
Codeend
Node TypeEND
Workflow TypesWorkflow only (not Agentflow)

Connections

DirectionDescription
IncomingReceives flow from workflow execution
OutgoingNone (terminates workflow)

Output Configuration

The End node defines the data contract for your workflow's response. Unlike standard processing nodes that have predefined outputs (data, success, error), End nodes use completely custom, user-defined output structures tailored to your specific workflow requirements.

End Node vs Component Outputs

TypeOutput StructurePurposeExample
Standard ComponentsFixed: data, success, errorInternal processingScript, Logger, API calls
End NodeCustom: User-defined fieldsExternal responseresult, status, metadata

Output Field Configuration

Each End node output field supports the same configuration options as Start node inputs:

OptionPurposeExampleApplies To
CodeUnique field identifier"customerData"All types
NameDisplay name"Customer Information"All types
TypeData typetext, integer, objectAll types
RequiredField must be present✓ Response statusAll types
ArrayMultiple values✓ List of resultsAll types
DescriptionDocumentation"Processed customer data"All types
Source ValueContext expression (see below)See Context Expressions sectionAll types

Output Field Types

TypeDescriptionExample Source Value
TextString values{{ctx.nodes.formatter.outputs.message}}
IntegerWhole numbers{{ctx.nodes.counter.outputs.total}}
FractionalDecimal numbers{{ctx.nodes.calculator.outputs.average}}
BooleanTrue/false values{{ctx.nodes.validator.outputs.isValid}}
ObjectJSON objects{{ctx.nodes.aggregator.outputs.summary}}
ArrayLists of values{{ctx.nodes.collector.outputs.items}}
FileFile references{{ctx.nodes.generator.outputs.reportFile}}

Context Expressions for Output Values

End nodes use context expressions to populate output values by accessing data from the workflow execution context. These expressions work in both Parameters mode (individual fields) and Inline mode (entire response body).

For comprehensive context documentation including expression syntax, built-in functions, and advanced patterns, see the Workflow Context guide.

Quick Context Reference

Basic Node Output Access:

{{ctx.nodes.nodeCode.outputs.outputField}}

Common Expression Patterns:

Data SourceExpressionExample Value
Start node inputs{{ctx.nodes.start.inputs.fieldName}}User-provided data
Node output data{{ctx.nodes.processor.outputs.data}}Processed results
Node success status{{ctx.nodes.validator.outputs.success}}true/false
Workflow variables{{ctx.vars.variableName}}Workflow-scoped variables
User information{{ctx.user.id}} / {{ctx.user.login}}Current user details

Parameters Mode Examples

Simple Status Response:

{
  "status": {
    "code": "status",
    "type": "text",
    "required": true,
    "sourceValue": "success",
    "description": "Operation completion status"
  }
}

Complex Data Response:

{
  "customerInfo": {
    "code": "customerInfo", 
    "type": "object",
    "required": true,
    "sourceValue": "{{ctx.nodes.customerProcessor.outputs.data}}",
    "description": "Processed customer information"
  },
  "orderCount": {
    "code": "orderCount",
    "type": "integer", 
    "required": false,
    "sourceValue": "{{ctx.nodes.orderCounter.outputs.total}}",
    "description": "Total number of orders processed"
  },
  "warnings": {
    "code": "warnings",
    "type": "text",
    "required": false,
    "isArray": true,
    "sourceValue": "{{ctx.nodes.validator.outputs.warnings}}",
    "description": "Processing warnings"
  }
}

Aggregated Results:

{
  "summary": {
    "code": "summary",
    "type": "object",
    "required": true,
    "sourceValue": "{
      \"processedCount\": {{ctx.nodes.processor.outputs.data.count}},
      \"startTime\": \"{{ctx.nodes.start.inputs.timestamp}}\",
      \"endTime\": \"{{ctx.current_timestamp}}\",
      \"results\": {{ctx.nodes.aggregator.outputs.data}}
    }",
    "description": "Workflow execution summary"
  }
}

Inline Mode

Return raw response body using the bodySourceValue field:

{
  "bodySourceValue": "{{ctx.nodes.fileProcessor.outputs.content}}"
}

Use Cases:

  • File content delivery (text files, JSON, CSV)
  • Simple string responses
  • Binary data streaming
  • Custom formatted responses

Output Mode Toggle

The End node UI provides a mode toggle that switches between:

ModeDescriptionUI BehaviorConfiguration
Parameters ModeCustom output fieldsShows "Outputs" section with add/remove fieldsUses individual output field configurations
Inline ModeRaw body contentShows "Outputs" text areaUses bodySourceValue for entire response body

Switching Modes:

  • Toggle "As inline" switch in the End node panel
  • Parameters mode: Define structured output fields
  • Inline mode: Write expression for entire response body

Mode Selection Guidelines:

  • Use Parameters Mode for: APIs with structured responses, multi-field outputs, validation requirements
  • Use Inline Mode for: File delivery, simple text responses, pass-through scenarios

HTTP Endpoint Configuration

Configure HTTP response behavior when workflow is triggered via HTTP endpoints. The End node provides separate configuration fields for HTTP responses that are independent of the output data structure.

SettingFieldDescriptionExample
MethodmethodHTTP methodGET, POST, PUT, PATCH, DELETE
PathpathURL endpoint path/api/v1/process-order
Status CodestatusSourceValueHTTP response status (static or dynamic)"200", "{{ctx.nodes.validator.outputs.statusCode}}"
HeadersheadersSourceValueCustom response headers (JSON expression)"{{\"Content-Type\": \"application/json\"}}"
BodybodySourceValueResponse body content (uses End node outputs)"{{ctx.nodes.end.outputs}}"

Status Source Value

The statusSourceValue field is separate from output configuration and specifically controls the HTTP status code returned to the caller. This field supports both static values and dynamic expressions.

Static Status Codes:

{
  "statusSourceValue": "200"     // Always return 200 OK
}

Dynamic Status Codes:

{
  "statusSourceValue": "{{ctx.nodes.validator.outputs.success ? 200 : 400}}"
}

Conditional Status Based on Results:

{
  "statusSourceValue": "{
    const errors = {{ctx.nodes.processor.outputs.error}};
    const success = {{ctx.nodes.processor.outputs.success}};
    
    if (!success && errors.includes('VALIDATION_ERROR')) return 400;
    if (!success && errors.includes('NOT_FOUND')) return 404;
    if (!success) return 500;
    return 200;
  }"
}

Status from Processing Results:

{
  "statusSourceValue": "{{ctx.nodes.apiCall.outputs.data.responseCode || 200}}"
}

### HTTP Status Codes

Configure appropriate status codes using the `statusSourceValue` field:

| Status | When to Use | Example statusSourceValue | Use Case |
|--------|-------------|---------------------------|----------|
| **200 OK** | Successful operation | `"200"` | Data retrieved/updated successfully |
| **201 Created** | Resource created | `"{{ctx.nodes.dbInsert.outputs.success ? 201 : 400}}"` | New record created |
| **204 No Content** | Successful DELETE | `"204"` | Resource deleted, no response body |
| **400 Bad Request** | Validation failed | `"{{ctx.nodes.validator.outputs.valid ? 200 : 400}}"` | Invalid input data |
| **404 Not Found** | Resource missing | `"{{ctx.nodes.lookup.outputs.found ? 200 : 404}}"` | Record doesn't exist |
| **500 Internal Server Error** | Processing error | `"{{ctx.nodes.processor.outputs.success ? 200 : 500}}"` | Workflow execution failed |

### Complete HTTP Configuration Example

```json
{
  "method": "POST",
  "path": "/api/v1/users",
  "statusSourceValue": "{{ctx.nodes.userCreator.outputs.success ? (ctx.nodes.userCreator.outputs.data.isNew ? 201 : 200) : 400}}",
  "headersSourceValue": "{
    \"Content-Type\": \"application/json\",
    \"X-Request-ID\": \"{{ctx.execution_id}}\",
    \"Cache-Control\": \"no-cache\"
  }",
  "bodySourceValue": "{{ctx.nodes.end.outputs}}"
}

## Response Patterns

### API Success Response

```json
{
  "success": true,
  "data": {
    "id": "{{createdId}}",
    "name": "{{processedName}}",
    "status": "active"
  },
  "meta": {
    "timestamp": "{{ctx.current_timestamp}}",
    "version": "v1"
  }
}

API Error Response

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "{{errorMessage}}",
    "details": "{{validationErrors}}"
  },
  "meta": {
    "timestamp": "{{ctx.current_timestamp}}",
    "requestId": "{{ctx.execution_id}}"
  }
}

Data Transformation Response

{
  "originalCount": "{{inputData.length}}",
  "processedCount": "{{outputData.length}}",
  "transformedData": "{{outputData}}",
  "processingTime": "{{executionTime}}ms"
}

File Processing Response

{
  "fileName": "{{originalFileName}}",
  "fileSize": "{{outputFileSize}}",
  "downloadUrl": "{{generatedUrl}}",
  "expiresAt": "{{urlExpiration}}"
}

Advanced Output Patterns

Multi-Node Data Aggregation:

{
  "customerProfile": {
    "code": "customerProfile",
    "type": "object",
    "sourceValue": "{{ctx.nodes.customerLookup.outputs.data}}",
    "description": "Customer information from database"
  },
  "orderHistory": {
    "code": "orderHistory", 
    "type": "object",
    "sourceValue": "{{ctx.nodes.orderProcessor.outputs.data}}",
    "description": "Processed order history"
  },
  "recommendations": {
    "code": "recommendations",
    "type": "object",
    "sourceValue": "{{ctx.nodes.aiRecommendations.outputs.data}}",
    "description": "AI-generated product recommendations"
  },
  "processingMetadata": {
    "code": "processingMetadata",
    "type": "object", 
    "sourceValue": "{
      \"startTime\": \"{{ctx.nodes.start.inputs.requestTimestamp}}\",
      \"endTime\": \"{{ctx.current_timestamp}}\",
      \"nodesExecuted\": [\"customerLookup\", \"orderProcessor\", \"aiRecommendations\"],
      \"executionId\": \"{{ctx.execution_id}}\"
    }",
    "description": "Workflow execution metadata"
  }
}

Conditional Output Based on Results:

{
  "result": {
    "code": "result",
    "type": "object",
    "sourceValue": "{
      \"status\": {{ctx.nodes.validator.outputs.success}} ? \"success\" : \"failure\",
      \"data\": {{ctx.nodes.processor.outputs.data}},
      \"errors\": {{ctx.nodes.validator.outputs.success}} ? [] : {{ctx.nodes.validator.outputs.error}},
      \"retryable\": {{ctx.nodes.errorHandler.outputs.data.canRetry}}
    }",
    "description": "Conditional response based on validation results"
  }
}

Array Aggregation from Multiple Nodes:

{
  "allResults": {
    "code": "allResults",
    "type": "object",
    "sourceValue": "{
      \"processed\": [{{ctx.nodes.step1.outputs.data}}, {{ctx.nodes.step2.outputs.data}}, {{ctx.nodes.step3.outputs.data}}],
      \"summary\": {
        \"totalItems\": {{ctx.nodes.step1.outputs.data.count}} + {{ctx.nodes.step2.outputs.data.count}} + {{ctx.nodes.step3.outputs.data.count}},
        \"successfulSteps\": [{{ctx.nodes.step1.outputs.success}}, {{ctx.nodes.step2.outputs.success}}, {{ctx.nodes.step3.outputs.success}}].filter(x => x).length
      }
    }",
    "description": "Aggregated results from parallel processing steps"
  }
}

Input Pass-Through with Processing Results:

{
  "originalRequest": {
    "code": "originalRequest",
    "type": "object", 
    "sourceValue": "{{ctx.nodes.start.inputs}}",
    "description": "Original input parameters"
  },
  "processedResponse": {
    "code": "processedResponse",
    "type": "object",
    "sourceValue": "{{ctx.nodes.finalProcessor.outputs.data}}",
    "description": "Processed workflow results"
  },
  "correlationId": {
    "code": "correlationId", 
    "type": "text",
    "sourceValue": "{{ctx.nodes.start.inputs.requestId}}",
    "description": "Request correlation identifier"
  }
}

Content Types

Configure appropriate content types for different response formats:

Content TypeUse CaseExample
application/jsonStructured dataAPI responses
text/plainPlain textLog files, simple text
text/csvTabular dataData exports
application/xmlXML dataSOAP responses
application/pdfGenerated documentsReports, invoices
image/pngGenerated imagesCharts, graphics

Error Handling

Error Response Structure

{
  "error": {
    "type": "{{errorType}}",
    "message": "{{errorMessage}}",
    "code": "{{errorCode}}",
    "timestamp": "{{ctx.current_timestamp}}"
  },
  "context": {
    "workflowId": "{{ctx.workflow_id}}",
    "executionId": "{{ctx.execution_id}}",
    "failedNode": "{{errorSource}}"
  }
}

Status Code Mapping

Map workflow errors to appropriate HTTP status codes:

{
  "validationError": 400,
  "authenticationError": 401,
  "authorizationError": 403,
  "notFoundError": 404,
  "rateLimit": 429,
  "processingError": 500,
  "serviceUnavailable": 503
}

Security and Headers

Security Headers

{
  "X-Content-Type-Options": "nosniff",
  "X-Frame-Options": "DENY",
  "X-XSS-Protection": "1; mode=block",
  "Strict-Transport-Security": "max-age=31536000"
}

CORS Headers

{
  "Access-Control-Allow-Origin": "{{allowedOrigin}}",
  "Access-Control-Allow-Methods": "GET, POST, PUT, PATCH, DELETE",
  "Access-Control-Allow-Headers": "Content-Type, Authorization",
  "Access-Control-Max-Age": "86400"
}

Cache Control

{
  "Cache-Control": "no-cache, no-store, must-revalidate",
  "Pragma": "no-cache",
  "Expires": "0"
}

Integration Patterns

REST API Pattern

{
  "method": "POST",
  "path": "/api/v1/users",
  "statusCode": 201,
  "headers": {
    "Content-Type": "application/json",
    "Location": "/api/v1/users/{{createdUserId}}"
  },
  "response": {
    "id": "{{createdUserId}}",
    "name": "{{userName}}",
    "email": "{{userEmail}}",
    "createdAt": "{{ctx.current_timestamp}}"
  }
}

Webhook Response Pattern

{
  "method": "POST",
  "path": "/webhooks/{{eventType}}",
  "statusCode": 200,
  "response": {
    "received": true,
    "eventId": "{{ctx.execution_id}}",
    "processedAt": "{{ctx.current_timestamp}}"
  }
}

File Download Pattern

{
  "method": "GET",
  "path": "/files/{{fileId}}/download",
  "statusCode": 200,
  "headers": {
    "Content-Type": "{{fileContentType}}",
    "Content-Disposition": "attachment; filename=\"{{fileName}}\"",
    "Content-Length": "{{fileSize}}"
  },
  "response": "{{fileContent}}"
}

Working with End Nodes in Studio

Configuring Outputs

Adding Output Fields (Parameters Mode):

  1. Open the End node by clicking on it
  2. In the "Outputs" section, click "+ Add Parameter"
  3. Select the field type (Text, Integer, Object, etc.)
  4. Configure field properties:
    • Code: Unique identifier for the field
    • Name: Display name for the field
    • Type: Data type (affects validation)
    • Required: Whether field must be present
    • Array: Enable for multiple values
    • Source Value: Expression to populate the field

Configuring HTTP Endpoint:

  1. In the End node panel, find the HTTP configuration section
  2. Configure:
    • Status Code: Static value ("200") or dynamic expression
    • Headers: JSON object with response headers
  3. The system automatically uses the node outputs for the response body

Mode Switching:

  • Toggle between Parameters and Inline mode using the "As inline" switch
  • Parameters mode: Structured field-by-field configuration
  • Inline mode: Single expression for entire response body

UI Features

FeatureLocationPurposeExample
Output FieldsOutputs sectionDefine response structurecustomerData, status, timestamp
Mode ToggleTop right of outputsSwitch between parameter/inline mode"As inline" checkbox
Status Code FieldHTTP configurationControl HTTP response status"{{success ? 200 : 400}}"
Headers FieldHTTP configurationSet response headers{"Content-Type": "application/json"}
Add ParameterOutputs sectionCreate new output fieldClick to add Text, Object, etc.

Studio Workflow Tips

Development Process:

  1. Plan Output Structure: Decide what data the workflow should return
  2. Start with Parameters Mode: Define structured outputs first
  3. Add Fields Incrementally: Create one output field at a time
  4. Test Expressions: Validate source value expressions work correctly
  5. Configure HTTP Settings: Set appropriate status codes and headers
  6. Switch to Inline Mode: If simple string response is preferred

Field Configuration Best Practices:

  • Use descriptive codes: Choose meaningful identifiers like customerProfile instead of data1
  • Set appropriate types: Match field types to actual data being returned
  • Mark required fields: Identify which outputs are mandatory
  • Add descriptions: Document what each field contains for team members
  • Order fields logically: Use the UI ordering to organize outputs sensibly

Best Practices

Response Design

  • Consistent structure: Use standardized response format
  • Include metadata: Add timestamps, versions, request IDs
  • Clear error messages: Provide actionable error information
  • Appropriate status codes: Use correct HTTP status codes

Performance Optimization

  • Minimize response size: Only include necessary data
  • Use appropriate caching: Set cache headers for static responses
  • Stream large responses: Consider streaming for large payloads
  • Compress responses: Enable gzip compression

Security Considerations

  • Sanitize outputs: Clean response data to prevent XSS
  • Rate limiting: Include rate limit headers
  • Audit logging: Log response data for security audits
  • Data privacy: Exclude sensitive information from responses

Troubleshooting

Common Issues

ProblemCauseSolution
Empty responseOutput mapping errorCheck field mappings
Wrong status codeIncorrect HTTP configurationReview status code settings
Header issuesInvalid header valuesValidate header format
JSON parsing errorsInvalid JSON structureValidate response structure

Debugging Tips

  1. Test responses: Use test values to verify output
  2. Check logs: Review execution logs for output generation
  3. Validate JSON: Ensure JSON responses are valid
  4. Monitor performance: Track response times and sizes

Response Validation

// Example response validation
const responseSchema = {
  type: "object",
  properties: {
    success: { type: "boolean" },
    data: { type: "object" },
    timestamp: { type: "string" }
  },
  required: ["success", "data"]
};