Input object
The input object is a property-style shorthand for request body fields. Instead of get('field'), you write input.field. It is automatically available in all expressions and expr blocks. This is a workflow mode concept - it reads the incoming request.
Basic usage
Property access
Access request body fields as properties:
yaml
# resources/example.yaml
after:
- set('query', input.q)
- set('userId', input.userId)
- set('items', input.items)
chat:
prompt: "User {{ get('userId') }} asked: {{ get('query') }}"In string interpolation
Use input directly in interpolated strings:
yaml
# resources/example.yaml
chat:
prompt: "Hello {{ input.name }}, you asked about {{ input.topic }}"Nested properties
Access nested object properties:
yaml
# resources/example.yaml
after:
- set('city', input.user.address.city)
- set('email', input.user.email)Comparison with unified API
The input object is a convenience wrapper around request body data. Both approaches work:
| Input Object | Unified API | Description |
|---|---|---|
input.field | get('field') | Request body field |
input.user.name | get('user').name | Nested property |
input.items[0] | get('items')[0] | Array element |
Example:
yaml
# resources/example.yaml -- using input object
after:
- set('name', input.name)
- set('email', input.user.email)
# Equivalent using Unified API
after:
- set('name', get('name'))
- set('email', get('user').email)When to use
Use input when:
- Accessing request body fields frequently
- Working with nested object structures
- Writing concise property access code
Use get() when:
- Need to access query parameters, headers, or other sources
- Need type hints for disambiguation
- Want consistency across all data access
Examples
Simple form data
yaml
# resources/create-user.yaml
actionId: createUser
validations:
required:
- name
- email
rules:
- field: name
type: string
- field: email
type: string
pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
after:
- set('userName', input.name)
- set('userEmail', input.email)
sql:
connectionName: main
query: |
INSERT INTO users (name, email)
VALUES ($1, $2)
params:
- get('userName')
- get('userEmail')Nested object access
yaml
# resources/example.yaml
after:
# Access nested properties
- set('shippingCity', input.order.shippingAddress.city)
- set('billingEmail', input.order.billing.email)
- set('itemCount', len(input.order.items))
chat:
prompt: |
Process order with {{ get('itemCount') }} items.
Shipping to: {{ get('shippingCity') }}Array processing
yaml
# resources/example.yaml
after:
- set('items', input.items)
- set('totalItems', len(get('items')))
- set('firstItem', get('items')[0])
chat:
prompt: |
Process {{ get('totalItems') }} items.
First item: {{ get('firstItem') }}Conditional based on input
yaml
# resources/example.yaml
after:
- set('hasItems', input.items != nil && len(input.items) > 0)
- set('isPremium', input.user.tier == 'premium')
validations:
skip:
- "!get('hasItems')"
chat:
prompt: |
{{ get('isPremium') ? 'Premium user' : 'Standard user' }}:
Process {{ len(input.items) }} items.Input object vs request body
The input object is the same as request.body:
yaml
# resources/example.yaml
after:
# These are equivalent:
- set('name1', input.name)
- set('name2', request.body.name)
- set('name3', get('name'))Limitations
- Body data only -
inputonly contains request body data, not query parameters or headers - No type hints - Cannot specify data source like
get('key', 'param') - No fallback - Returns nil if property doesn't exist (use
default()for fallbacks)
Best practices
- Use for body data - Perfect for POST/PUT request bodies
- Combine with validation - Validate input structure before using
- Use default() for safety -
default(input.field, 'fallback') - Prefer get() for flexibility - When you need query params, headers, or type hints
See also
- Unified API - Primary API for data access
- Request object - Full request access
- Validation and control flow - Input validation
