> ## Documentation Index
> Fetch the complete documentation index at: https://docs.frayme.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Variables & templating

> How {{interpolation}} works in node configs, body templates, and AI prompts.

Every node configuration string supports `{{...}}` interpolation against the run context. The same convention spans HTTP bodies, AI prompts, rule conditions, decision-table cells, and labels.

## What you can reference

<AccordionGroup>
  <Accordion title="Workflow input — input.*">
    The original payload posted to the workflow.

    ```text theme={null}
    {{input.applicant_id}}
    {{input.declared_country}}
    {{input.declared_address.street}}
    {{input.counterpart.key}}
    ```
  </Accordion>

  <Accordion title="Upstream node outputs">
    Whatever each node wrote to `outputVariable`.

    ```text theme={null}
    {{sumsub_applicant.applicant_id}}
    {{sumsub_identity.review_answer}}
    {{ai_risk_synthesis.risk_band}}
    {{crystal_risk.signals}}
    {{bdc_counterpart.pep_hit}}
    ```

    Rules and decision tables also write to the top level (their `outputFields`):

    ```text theme={null}
    {{region_check}}
    {{rewrite_valid}}
    {{counterpart_edd_required}}
    {{onchain_band}}
    ```
  </Accordion>

  <Accordion title="Workflow parameters — params.*">
    Top-level tunables declared at the workflow's `parameters` array. Same prefix shape as `input` so they're easy to spot at a glance.

    ```text theme={null}
    {{params.max_address_length}}
    {{params.notification_callback}}
    {{params.block_threshold}}
    ```
  </Accordion>

  <Accordion title="System-injected values">
    ```text theme={null}
    {{workflow_run_id}}      // UUID per run
    {{now_unix}}             // Unix seconds at evaluation
    {{first_fired_rule}}     // convenience for joining alerts
    ```
  </Accordion>
</AccordionGroup>

## Where you can use it

| Context                         | Example                                                                                                  |
| ------------------------------- | -------------------------------------------------------------------------------------------------------- |
| **Custom API endpoint**         | `https://receita.gov.br/cpf/{{input.cpf}}`                                                               |
| **Custom API body**             | `"applicant_id": "{{input.applicant_id}}"`                                                               |
| **HTTP header**                 | `X-Workflow-Run: {{workflow_run_id}}`                                                                    |
| **AI prompt**                   | `Applicant: {{input.full_name}}, {{input.dob}}, {{input.declared_country}}.`                             |
| **Rule clause value**           | `{{address_length}}` — note: usually rules use literal values; interpolation is for derived comparisons. |
| **Decision table output**       | `{{sumsub_applicant.applicant_id}}`                                                                      |
| **Manual review display field** | `value: "input.full_name"` (no braces — the field path is referenced directly)                           |
| **Terminal output schema**      | n/a — the schema is the field list, not a template                                                       |

## Dot-path vs literal evaluation

There are two slightly different conventions:

* **Inside `{{...}}`** the path is interpolated. `{{input.declared_address.street}}` resolves to a string.
* **In rule/decisionTable `variable:` fields** the path is passed as a literal string. `variable: "input.declared_country"` is the path the evaluator reads, not an interpolation.

This is why you see both `"variable": "input.declared_country"` (without braces) and `"value": "{{input.declared_address.street}}"` (with braces) in the same node.

## Helpers that *are* available

The expression layer supports a handful of helpers:

| Helper                    | Example                                                                                               |
| ------------------------- | ----------------------------------------------------------------------------------------------------- |
| `max_by(list, key)`       | `{{max_by(input.ubo_declared, 'ownership_pct')}}` — picks the list item with the highest field value. |
| `length` accessor         | `input.declared_address.street.length` — string length.                                               |
| `in` / `not_in` operators | Rule clauses, comma-separated value lists.                                                            |

More advanced transforms live in the [`code` node](/workflows/nodes/code) so the templating layer stays small and predictable.

## What is *not* templated

* **Vendor API base URLs** in `dataSource` nodes — Frayme resolves these from the Data Source registry.
* **Provider IDs** — `providerId: "7"` is the registry pointer; it isn't a template.
* **The `connectionName` reference** — a literal key into the workflow's `connections` map.
