API Response Resource
apiResponse: builds and returns the HTTP response sent back to the caller. It is always the last resource in the dependency chain -- the resource pointed to by targetActionId in workflow.yaml.
Where it runs
Workflow mode only. apiResponse: is the terminal node that formats the HTTP response returned by a workflow. In agent mode, apiResponse.response is what the engine returns to the LLM as the tool result -- but the resource itself is not a tool; the whole workflow is.
Basic Usage
# resources/respond.yaml
actionId: responseResource
name: API Response
requires:
- llmResource
apiResponse:
success: true
response:
data: get('llmResource')
headers:
Content-Type: application/jsonConfiguration Options
# resources/example.yaml
apiResponse:
success: true # Boolean: request success status
response: # Response body (any structure)
field: value
nested:
key: value
headers:
Header-Name: value
statusCode: 200 # HTTP status code (optional)
model: llama3.2:1b
backend: fileResponse Structure
Simple Response
# resources/example.yaml
apiResponse:
success: true
response:
message: "Hello, World!"Output:
{
"success": true,
"response": {
"message": "Hello, World!"
}
}Dynamic Response
# resources/example.yaml
apiResponse:
success: true
response:
query: get('q')
answer: get('llmResource').answer
timestamp: info('timestamp')
request_id: info('ID')Nested Structure
# resources/example.yaml
apiResponse:
success: true
response:
user:
id: get('user_id')
name: get('userResource').name
data:
items: get('dataResource')
count: len(get('dataResource'))
pagination:
page: get('page', '1')
limit: get('limit', '10')Custom Headers
Set response headers:
# resources/example.yaml
apiResponse:
success: true
response:
data: get('result')
headers:
Content-Type: application/json
X-Request-Id: info('ID')
X-Processing-Time: "{{ get('processingTime') }}ms"
Cache-Control: "max-age=3600"Adding Metadata
Include model and backend information in responses:
# resources/example.yaml
apiResponse:
success: true
response:
answer: get('llmResource')
model: llama3.2:1b
backend: fileAutomatic Metadata: If an LLM resource was used in the workflow, model and backend information are automatically added to the response metadata (unless explicitly specified).
# LLM resource used earlier
actionId: llmResource
chat:
model: llama3.2:1b
backend: ollama
prompt: "{{ get('q') }}"
---
# Response automatically includes model/backend
actionId: responseResource
requires: [llmResource]
apiResponse:
success: true
response:
answer: get('llmResource')
# model and backend added automaticallyResponse format:
{
"success": true,
"data": {
"answer": "The response text..."
},
"meta": {
"model": "llama3.2:1b",
"backend": "file"
}
}Manual Metadata
You can also manually specify metadata to override automatic values:
# resources/example.yaml
apiResponse:
success: true
response:
answer: get('llmResource')
model: custom-model
backend: custom-backend
headers:
X-Custom-Header: valueNote: Manual metadata takes precedence over automatic metadata.
Error Responses
For error handling, use preflight checks or conditional responses:
Preflight Validation
# resources/example.yaml
validations:
check:
- get('user_id') != ''
error:
code: 400
message: User ID is required
apiResponse:
success: true
response:
user: get('userResource')Conditional Success
# resources/example.yaml
apiResponse:
success: get('operationResource').status == 'success'
response:
result: get('operationResource').data
error: get('operationResource').errorExamples
Chat API Response
# resources/chat-response.yaml
actionId: chatResponse
requires: [llmResource]
apiResponse:
success: true
response:
answer: get('llmResource').answer
model: llama3.2:1b
usage:
prompt_tokens: get('llmResource').prompt_tokens
completion_tokens: get('llmResource').completion_tokens
headers:
Content-Type: application/jsonFile Upload Response
# resources/upload-response.yaml
actionId: uploadResponse
requires: [processFile]
apiResponse:
success: true
response:
message: File processed successfully
file:
name: get('file', 'filepath')
type: get('file', 'filetype')
size: get('processFile').size
result: get('processFile').analysis
headers:
Content-Type: application/jsonPaginated List Response
# resources/list-response.yaml
actionId: listResponse
requires: [fetchItems]
apiResponse:
success: true
response:
items: get('fetchItems')
pagination:
page: get('page', '1')
limit: get('limit', '10')
total: get('fetchItems').total
has_more: get('fetchItems').has_more
headers:
Content-Type: application/json
X-Total-Count: get('fetchItems').totalMulti-Resource Response
# resources/dashboard-response.yaml
actionId: dashboardResponse
requires:
- userResource
- statsResource
- notificationsResource
apiResponse:
success: true
response:
user:
id: get('userResource').id
name: get('userResource').name
email: get('userResource').email
stats:
views: get('statsResource').views
engagement: get('statsResource').engagement
notifications:
unread: get('notificationsResource').unread
items: get('notificationsResource').items
headers:
Content-Type: application/jsonError Response Pattern
# Successful case
actionId: successResponse
requires: [dataResource]
validations:
skip:
- get('dataResource').error != null
apiResponse:
success: true
response:
data: get('dataResource').data
---
# Error case
actionId: errorResponse
requires: [dataResource]
validations:
skip:
- get('dataResource').error == null
apiResponse:
success: false
response:
error:
code: get('dataResource').error.code
message: get('dataResource').error.messageResponse Transformation
Transform data before returning:
# resources/transformed-response.yaml
actionId: transformedResponse
requires: [rawData]
after:
- set('formatted', filter(get('rawData'), .active == true))
apiResponse:
success: true
response:
data: get('formatted')
original_count: len(get('rawData'))
processed_count: len(get('formatted'))Best Practices
- Always set Content-Type - Usually
application/json - Include request ID - Helps with debugging
- Be consistent - Use the same structure across endpoints
- Include metadata - Model version, timing, etc.
- Handle errors gracefully - Clear error messages
See Also
- Resources Overview -- all resource types
- LLM Resource -- AI model integration
- Unified API -- data access patterns
