Using Input and Output Event Data
Understanding data flow through your automation is important for building effective Flows. This explains how to access, reference, and manipulate event data.
Event Accumulation
Section titled “Event Accumulation”Events accumulate data as they flow through blocks. Each block adds its output to existing event data using the block’s camelCase name as the key.
Example flow: “Get User Name” → “Get User Role” → “Access Check”
Final event structure:
{ "getUserName": { "name": "John Doe", "email": "johndoe@example.org" }, "getUserRole": { "role": "admin" }, "accessCheck": { "allowed": true }}Accessing Data in Configuration
Section titled “Accessing Data in Configuration”The outputs Variable
Section titled “The outputs Variable”Access outputs of previous blocks through the outputs variable:
outputs.getUserName.name // "John Doe"outputs.getUserRole.role // "admin"outputs.accessCheck.allowed // trueExamples:
Section titled “Examples:”// Slack message`Hello <@${outputs.getUserName.name}>! Your role is: ${outputs.getUserRole.role}`
// Conditional logicoutputs.accessCheck.allowed && outputs.getUserRole.role === 'admin'
// Dynamic URL`https://api.example.com/users/${outputs.getUserName.email}/permissions`The ref() Function
Section titled “The ref() Function”While outputs gives you access to event data from previous blocks, the ref() function lets you reference signals from blocks with lifecycles (e.g. an S3 Bucket Resource)
ref("signal.blockName.signalName")Example:
ref("signal.myS3Bucket.arn") // AWS S3 bucket ARN referenceBlock Name Conversion
Section titled “Block Name Conversion”Block names automatically convert to camelCase for event data keys. Numbers are included in the camelCase name, and content within parentheses is automatically excluded from the conversion.
| Block Name | Data Key |
|---|---|
| ”Get User Name” | getUserName |
| ”API Response” | apiResponse |
| ”Process Data 2” | processData2 |
| ”Test Block (3)“ | testBlock |
| ”Profile (Beta)“ | profile |
Common Data Operations
Section titled “Common Data Operations”String Data
Section titled “String Data”`User: ${outputs.userLookup.name} (${outputs.userLookup.email})` // String interpolationoutputs.userLookup.name.toUpperCase() // Data transformationoutputs.userLookup.email.includes('@company.com') // String method checkNumeric Data
Section titled “Numeric Data”outputs.calculation.result * 1.2 // Mathematical operationsoutputs.metrics.count + outputs.metrics.errors // AdditionArrays and Objects Operations
Section titled “Arrays and Objects Operations”outputs.userList.users.length // Array lengthoutputs.userList.users.map(user => user.name) // Array transformationoutputs.userList.users.filter(user => user.active) // Array filtering
outputs.apiResponse.data.items[0].id // Array element accessoutputs.configuration.settings.timeout // Property accessBoolean Logic
Section titled “Boolean Logic”outputs.validation.isValid && outputs.permissions.hasAccess // Boolean operationsoutputs.userProfile.role === 'admin' // Property check!outputs.check.failed || outputs.retry.available // Fallback logic`Display Name: ${outputs.getUserMetadata.user.display_name || 'Not set'}` // Default assignmentoutputs.error.occurred ? `Error: ${outputs.error.message}` : `Success: Processed ${outputs.result.count} items` // Conditional logicoutputs.performance.responseTime > 1000 // ComparisonComplex Transformations
Section titled “Complex Transformations”Use anonymous functions for multi-step processing:
(function() { const users = outputs.userQuery.results || []; const activeUsers = users.filter(user => user.status === 'active'); return { total: activeUsers.length, names: activeUsers.map(user => user.name), lastLogin: Math.max(...activeUsers.map(user => new Date(user.lastLogin).getTime())) };})()Testing Your Expressions
Section titled “Testing Your Expressions”After connecting blocks, Spacelift shows input schemas so you know what data is available. Use the debug feature to send test events and verify your expressions work correctly.