Documentation Index
Fetch the complete documentation index at: https://docs.anyreach.ai/llms.txt
Use this file to discover all available pages before exploring further.
Expressions are how you reference and transform data inside step configurations. Anyreach supports two expression flavors:
| Flavor | Syntax | When to use |
|---|
| JSONata | {{ ... }} | Deterministic transformations: addressing fields, filtering arrays, basic math, type checks |
| AI | ${ ... } | Free-text classification, extraction, generation: anything an LLM does well |
You can use both inside the same step (different fields), but you cannot mix them in the same expression — see Condition step for the constraint.
JSONata Expressions
JSONata is a query language for JSON. The minimum you need:
| Want to… | Write… |
|---|
| Get a top-level input field | {{ n3.customer_email }} or {{ input.customer_email }} |
| Get a step’s output field | {{ n3.body.id }} |
| Compare values | {{ n3.score > 50 }} |
| Boolean logic | {{ n3.score > 50 and n3.tier = 'gold' }} |
| Filter an array | {{ n3.contacts[tier = 'gold'] }} |
| Map an array | {{ n3.contacts.email }} (returns an array of emails) |
| Default value | {{ n3.name ? name : 'friend' }} |
| String concat | {{ n3.first_name & ' ' & n3.last_name }} |
See JSONata cookbook for more.
AI Expressions
${...} sends the contents (with {{...}} interpolations resolved first) to an LLM and replaces the expression with the response.
"summary": "${a one-sentence summary of {{n3.transcript}}}"
"intent": "${classify the intent: billing, support, or sales. transcript: {{n3.transcript}}}"
"is_qualified": "${is the lead qualified? answer yes or no. transcript: {{n3.transcript}}}"
For AI to behave reliably, be specific about the response format. “answer yes or no” is much better than “is the lead qualified?”.
See AI expressions for more.
Pure vs interpolated
A field whose entire value is one expression is pure:
"customer_id": "{{ n3.body.id }}" → pure JSONata
"summary": "${a summary of: {{n3.transcript}}}" → pure AI
A field with surrounding text is interpolated (the whole thing becomes a string):
"message": "Hello {{ n3.body.first_name }}, welcome!" → string
Why this matters
Pure expressions preserve types — if n3.body.id is an integer, customer_id is an integer. Interpolated expressions always produce strings.
This affects HTTP request bodies (where APIs may require integer IDs, not strings) and Output schemas (where validation enforces types).
Evaluation order
When a step is about to run, the platform evaluates expressions in its config:
- JSONata is resolved first, top to bottom, against the current
ctx
- AI is resolved next, with
{{...}} interpolations already replaced
This means you can reference upstream steps inside AI prompts:
"intent": "${what is the user's intent in this transcript? {{`Last turn`.body.text}}}"
The {{...}} is replaced with the actual transcript before the LLM sees the prompt.
Where expressions are evaluated
Most fields in most step types support expressions. A few notable places:
| Step | Expression-evaluated fields |
|---|
| HTTP API | url, headers (values), query_params (values), body (recursively) |
| Condition | each condition’s condition |
| Output | each output_data value |
| Action | each operation_input value |
| Code | not in code itself — the code reads ctx directly |
Code steps don’t use expressions inside the source code — your Python reads ctx natively.