# 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”](#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”](#accessing-data-in-configuration)
### The `outputs` Variable
[Section titled “The outputs Variable”](#the-outputs-variable)
Access outputs of previous blocks through the `outputs` variable:


**

```
outputs.getUserName.name     // "John Doe"outputs.getUserRole.role     // "admin"outputs.accessCheck.allowed // true
```

#### Examples:
[Section titled “Examples:”](#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”](#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 reference
```

## Block Name Conversion
[Section titled “Block Name Conversion”](#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”](#common-data-operations)
### String Data
[Section titled “String Data”](#string-data)

**

```
`User: ${outputs.userLookup.name} (${outputs.userLookup.email})` // String interpolationoutputs.userLookup.name.toUpperCase() // Data transformationoutputs.userLookup.email.includes('@company.com') // String method check
```

### Numeric Data
[Section titled “Numeric Data”](#numeric-data)

**

```
outputs.calculation.result * 1.2 // Mathematical operationsoutputs.metrics.count + outputs.metrics.errors // Addition
```

### Arrays and Objects Operations
[Section titled “Arrays and Objects Operations”](#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 access
```

### Boolean Logic
[Section titled “Boolean Logic”](#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 // Comparison
```

### Complex Transformations
[Section titled “Complex Transformations”](#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”](#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.