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

# Flow Schema

> Field-by-field reference for the Flow JSON document.

The **Flow** document is the JSON body you submit under `compose.flow` in a `POST /compose` request. This page is a reference for the wire format the service accepts. The authoritative schema ships with [`@lifi/composer-sdk`](https://www.npmjs.com/package/@lifi/composer-sdk); when a detail here conflicts with the SDK, the SDK wins — file an issue.

## Top-level: `Flow`

```json theme={"system"}
{
  "version": 1,
  "id": "my-flow",
  "chainId": 1,
  "inputs": [ /* FlowInput[] */ ],
  "nodes":  [ /* Call[] */ ]
}
```

| Field     | Type             | Required | Notes                                                                                            |
| --------- | ---------------- | -------- | ------------------------------------------------------------------------------------------------ |
| `version` | literal `1`      | yes      | Reserved for forward compatibility.                                                              |
| `id`      | `string`         | yes      | User-defined flow id. SDK generates a UUID when omitted.                                         |
| `chainId` | positive integer | yes      | The EVM chain every node targets.                                                                |
| `inputs`  | `FlowInput[]`    | yes      | May be empty. Input `name` fields are user-defined.                                              |
| `nodes`   | `Call[]`         | yes      | Ordered. Node `id` fields are user-defined and are how other nodes reference this one's outputs. |

## `FlowInput`

A union of **resource inputs** and **handle inputs**. Schema: `FlowInputSchema = Union(ResourceInputSchema, HandleInputSchema)`.

### `ResourceInput`

```json theme={"system"}
{
  "name": "amountIn",
  "resource": { "kind": "erc20", "token": "0xC02a…Cc2", "chainId": 1 }
}
```

| Field      | Type       | Notes                                                                                                            |
| ---------- | ---------- | ---------------------------------------------------------------------------------------------------------------- |
| `name`     | `string`   | Unique within `inputs`. Used as the `input.<name>` ref target.                                                   |
| `resource` | `Resource` | `{ kind: "native", chainId }` or `{ kind: "erc20", token, chainId }`. `chainId` must equal the flow's `chainId`. |

Schemas: `ResourceInputSchema`, `ResourceSchema`.

### `HandleInput`

```json theme={"system"}
{
  "name": "deadline",
  "type": "uint256"
}
```

| Field  | Type      | Notes                                                                                                   |
| ------ | --------- | ------------------------------------------------------------------------------------------------------- |
| `name` | `string`  | Unique within `inputs`.                                                                                 |
| `type` | `SolType` | One of `uint8..uint256`, `int128`, `int256`, `address`, `bool`, `bytes`, `bytes4`, `bytes32`, `string`. |

Schema: `HandleInputSchema`, `SolTypeSchema`.

## `Call` (node)

```json theme={"system"}
{
  "id": "swap",
  "op": "lifi.swap",
  "bind": {
    "amountIn": { "$ref": "input.amountIn" }
  },
  "config": {
    "resourceOut": { "kind": "erc20", "token": "0xA0b8…eB48", "chainId": 1 },
    "slippage": 0.03
  },
  "guards": [
    { "kind": "slippage", "port": "amountOut", "bps": 100 }
  ]
}
```

| Field    | Type                        | Notes                                                                                            |
| -------- | --------------------------- | ------------------------------------------------------------------------------------------------ |
| `id`     | `string`                    | Unique within the flow. Cannot match a reserved ref scope (`input`, `context`, `literal`).       |
| `op`     | `string`                    | Registered op name in the manifest.                                                              |
| `bind`   | `Record<string, BindValue>` | Maps input port name → ref or literal. Defaults to `{}`.                                         |
| `config` | `Record<string, unknown>`   | Op-specific configuration. Defaults to `{}`. Validated against the op's manifest `configSchema`. |
| `guards` | `AppliedGuard[]`            | Optional. Each entry `{ kind, ...config }` with the guard's config.                              |

Schemas: `CallSchema`, `AppliedGuardSchema`.

## `BindValue`

`bind` entries are one of two shapes. Schema: `BindValueSchema = Union(RefSchema, LiteralBindingSchema)`.

### `Ref`

```json theme={"system"}
{ "$ref": "input.amountIn" }
```

`$ref` is a dotpath with exactly one of three shapes — see [References](/composer/composer-api/concepts/ref-grammar):

* `input.<name>`
* `context.<sender|executionAddress>`
* `<nodeId>.<port>`

Schema: `RefSchema`.

### `LiteralBinding`

```json theme={"system"}
{ "kind": "uint256", "value": "1000000000000000000" }
```

| Field   | Type      | Notes                                                                                                          |
| ------- | --------- | -------------------------------------------------------------------------------------------------------------- |
| `kind`  | `SolType` | The literal's Solidity type.                                                                                   |
| `value` | `string`  | Decimal for integer types; hex (`0x…`) for `bytes*`; plain string for `string`; `"true"`/`"false"` for `bool`. |

Schema: `LiteralBindingSchema`.

## `AppliedGuard`

```json theme={"system"}
{ "kind": "slippage", "port": "amountOut", "bps": 100 }
```

| Field          | Type     | Notes                                                                         |
| -------------- | -------- | ----------------------------------------------------------------------------- |
| `kind`         | `string` | Guard type registered in the manifest.                                        |
| *(additional)* | any      | Guard-specific config. Validated against the guard's manifest `configSchema`. |

Schema: `AppliedGuardSchema`.

## `Resource`

```json theme={"system"}
{ "kind": "native", "chainId": 1 }
{ "kind": "erc20", "token": "0xA0b8…eB48", "chainId": 1 }
```

| Variant  | Fields                                        |
| -------- | --------------------------------------------- |
| `native` | `kind: "native"`, `chainId`                   |
| `erc20`  | `kind: "erc20"`, `token` (address), `chainId` |

Schema: `ResourceSchema`.

## `SolType`

Literal union of supported Solidity scalar types: `uint8`, `uint16`, `uint32`, `uint64`, `uint128`, `uint256`, `int128`, `int256`, `address`, `bool`, `bytes`, `bytes4`, `bytes32`, `string`.

Schema: `SolTypeSchema`.

## Worked example

The `swap-and-zap` quickstart produces a Flow that, after `builder.build()`, serialises to:

```json theme={"system"}
{
  "version": 1,
  "id": "swap-and-zap-weth-to-aave",
  "chainId": 1,
  "inputs": [
    {
      "name": "amountIn",
      "resource": { "kind": "erc20", "token": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "chainId": 1 }
    }
  ],
  "nodes": [
    {
      "id": "swap",
      "op": "lifi.swap",
      "bind": {
        "amountIn": { "$ref": "input.amountIn" }
      },
      "config": {
        "resourceOut": { "kind": "erc20", "token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "chainId": 1 },
        "slippage": 0.03
      }
    },
    {
      "id": "zap",
      "op": "lifi.zap",
      "bind": {
        "amountIn": { "$ref": "swap.amountOut" }
      },
      "config": {
        "resourceOut": { "kind": "erc20", "token": "0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c", "chainId": 1 }
      },
      "guards": [
        { "kind": "slippage", "port": "amountOut", "bps": 100 }
      ]
    }
  ]
}
```

## See also

* [Flow Structure](/composer/composer-api/concepts/flow-anatomy) — prose walkthrough of the same fields.
* [References](/composer/composer-api/concepts/ref-grammar) — `$ref` parsing rules.
* [`@lifi/compose-spec`](https://unpkg.com/browse/@lifi/compose-spec/) — SDK types that match this wire format.
