Skip to main content
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; when a detail here conflicts with the SDK, the SDK wins — file an issue.

Top-level: Flow

{
  "version": 1,
  "id": "my-flow",
  "chainId": 1,
  "inputs": [ /* FlowInput[] */ ],
  "nodes":  [ /* Call[] */ ]
}
FieldTypeRequiredNotes
versionliteral 1yesReserved for forward compatibility.
idstringyesUser-defined flow id. SDK generates a UUID when omitted.
chainIdpositive integeryesThe EVM chain every node targets.
inputsFlowInput[]yesMay be empty. Input name fields are user-defined.
nodesCall[]yesOrdered. 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

{
  "name": "amountIn",
  "resource": { "kind": "erc20", "token": "0xC02a…Cc2", "chainId": 1 }
}
FieldTypeNotes
namestringUnique within inputs. Used as the input.<name> ref target.
resourceResource{ kind: "native", chainId } or { kind: "erc20", token, chainId }. chainId must equal the flow’s chainId.
Schemas: ResourceInputSchema, ResourceSchema.

HandleInput

{
  "name": "deadline",
  "type": "uint256"
}
FieldTypeNotes
namestringUnique within inputs.
typeSolTypeOne of uint8..uint256, int128, int256, address, bool, bytes, bytes4, bytes32, string.
Schema: HandleInputSchema, SolTypeSchema.

Call (node)

{
  "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 }
  ]
}
FieldTypeNotes
idstringUnique within the flow. Cannot match a reserved ref scope (input, context, literal).
opstringRegistered op name in the manifest.
bindRecord<string, BindValue>Maps input port name → ref or literal. Defaults to {}.
configRecord<string, unknown>Op-specific configuration. Defaults to {}. Validated against the op’s manifest configSchema.
guardsAppliedGuard[]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

{ "$ref": "input.amountIn" }
$ref is a dotpath with exactly one of three shapes — see References:
  • input.<name>
  • context.<sender|executionAddress>
  • <nodeId>.<port>
Schema: RefSchema.

LiteralBinding

{ "kind": "uint256", "value": "1000000000000000000" }
FieldTypeNotes
kindSolTypeThe literal’s Solidity type.
valuestringDecimal for integer types; hex (0x…) for bytes*; plain string for string; "true"/"false" for bool.
Schema: LiteralBindingSchema.

AppliedGuard

{ "kind": "slippage", "port": "amountOut", "bps": 100 }
FieldTypeNotes
kindstringGuard type registered in the manifest.
(additional)anyGuard-specific config. Validated against the guard’s manifest configSchema.
Schema: AppliedGuardSchema.

Resource

{ "kind": "native", "chainId": 1 }
{ "kind": "erc20", "token": "0xA0b8…eB48", "chainId": 1 }
VariantFields
nativekind: "native", chainId
erc20kind: "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:
{
  "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