---
title: "Execute a single node with inline input variables"
method: POST
path: "/nodes:run"
tags: ["Nodes"]
---

# Execute a single node with inline input variables

`POST /nodes:run`

Useful for SDK testing flows — run a node definition against
provided input variables without persisting a workflow. Honors
`node.config.chainId` (overrides body `chainId`). Requires a user
Bearer JWT; partner assertion alone is not sufficient.

## Request body

- RunNodeRequest
  - `node` union, required
    - object
      - `type` 'ethTransfer', required
      - `config` ETHTransferNodeConfig, required
        - `destination` string, required — Lowercase or checksummed hex EOA / contract address.
        - `amount` string, required — Amount in wei (decimal string for big-int safety). Special value `max` withdraws the entire balance.
        - `chainId` integer, required — Numeric chain ID (e.g. 11155111 for Sepolia, 8453 for Base). On chain-aware trigger/node configs this is required and must be a configured chain; on query/filter params it is optional.
    - object
      - `type` 'contractWrite', required
      - `config` ContractWriteNodeConfig, required
        - `contractAddress` string, required — Lowercase or checksummed hex EOA / contract address.
        - `callData` string — Arbitrary-length hex-encoded byte string.
        - `contractAbi` unknown[]
          - unknown
        - `methodCalls` MethodCall[]
          - `methodName` string, required
          - `callData` string — Arbitrary-length hex-encoded byte string.
          - `contractAddress` string — Lowercase or checksummed hex EOA / contract address.
          - `applyToFields` string[]
          - `methodParams` string[]
        - `isSimulated` boolean — When true, use Tenderly simulation instead of sending a real UserOp.
        - `value` string — ETH value to send with the call (wei, decimal string).
        - `gasLimit` string — Custom gas limit (decimal string).
        - `chainId` integer, required — Numeric chain ID (e.g. 11155111 for Sepolia, 8453 for Base). On chain-aware trigger/node configs this is required and must be a configured chain; on query/filter params it is optional.
    - object
      - `type` 'contractRead', required
      - `config` ContractReadNodeConfig, required
        - `contractAddress` string, required — Lowercase or checksummed hex EOA / contract address.
        - `contractAbi` unknown[]
          - unknown
        - `methodCalls` MethodCall[]
          - `methodName` string, required
          - `callData` string — Arbitrary-length hex-encoded byte string.
          - `contractAddress` string — Lowercase or checksummed hex EOA / contract address.
          - `applyToFields` string[]
          - `methodParams` string[]
        - `chainId` integer, required — Numeric chain ID (e.g. 11155111 for Sepolia, 8453 for Base). On chain-aware trigger/node configs this is required and must be a configured chain; on query/filter params it is optional.
    - object
      - `type` 'graphqlQuery', required
      - `config` GraphQLQueryNodeConfig, required
        - `url` string, uri, required
        - `query` string, required
        - `variables` object
    - object
      - `type` 'restApi', required
      - `config` RestAPINodeConfig, required
        - `url` string, uri, required
        - `method` 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS', required
        - `headers` object
        - `body` string
        - `options` object — Generic options bag for backend features on terminal RestAPI nodes. `summarize: true` opts a SendGrid /v3/mail/send or Telegram /sendMessage node into the aggregator's context-memory summarizer, which composes a subject + HTML body from the workflow's execution context and injects them into the outgoing request. Without this field set, the aggregator falls back to the deterministic summarizer (no LLM polish).
          - `summarize` boolean — When true on a terminal SendGrid or Telegram node, ComposeSummarySmart runs at execution time and fills in the empty content.value / text slot with an AI-generated body. No-op on non-notification URLs.
    - object
      - `type` 'customCode', required
      - `config` CustomCodeNodeConfig, required
        - `lang` 'javascript' | 'json' | 'graphql' | 'handlebars', required — Language/format of an inline payload (e.g., custom code source, manual trigger data). Mirrors the proto `Lang` enum minus the `LANG_` prefix. Wire values are lowercase.
        - `source` string, required
    - object
      - `type` 'branch', required
      - `config` BranchNodeConfig, required
        - `conditions` BranchCondition[], required
          - `id` string, required
          - `type` 'if' | 'elseIf' | 'else'
          - `expression` string, required — JavaScript-evaluated boolean expression.
    - object
      - `type` 'filter', required
      - `config` FilterNodeConfig, required
        - `inputVariable` string, required — Template path for the source array (e.g., `{{custom_code1.data}}`).
        - `expression` string, required — JavaScript predicate evaluated per item.
    - object
      - `type` 'loop', required
      - `config` LoopNodeConfig, required — Iterates over an input array, running an inner Node per item. The runner node is one of the chain-aware or chain-agnostic node types; a chain-aware runner must specify its own required `chainId` (there is no inheritance from the loop or workflow).
        - `inputVariable` string, required — Template path for the iterable (e.g., `{{settings.addressList}}`).
        - `iterVar` string — Name of the per-iteration variable (defaults to `value`).
        - `runner` Node, required — recursive
    - object
      - `type` 'balance', required
      - `config` BalanceNodeConfig, required
        - `address` string, required — Lowercase or checksummed hex EOA / contract address.
        - `chain` string, required — Chain name or numeric ID (e.g., `ethereum`, `base`, `1`, `8453`).
        - `includeSpam` boolean
        - `includeZeroBalances` boolean
        - `minUsdValueCents` integer — Filter out tokens with USD value below this many cents.
        - `tokenAddresses` EthereumAddress[] — Restrict to these tokens. Empty = fetch all.
    - object
      - `type` 'await', required
      - `config` AwaitNodeConfig, required — Pauses the workflow until a wake arrives (durable execution). Two mutually exclusive flavors: the external-signal flavor (human approval — set `channel`, e.g. a Telegram approve/reject), or the chain-event flavor (cross-chain — set `chainEvent` to pause until an operator observes that on-chain event, e.g. a bridge arrival on another chain). Exactly one flavor must be configured.
        - `channel` 'telegram' | 'api' — External-signal flavor — signal channel: `telegram` or `api`.
        - `approvers` string[] — External-signal flavor — authorized approver identities. Empty = the workflow owner. NOTE (v1): not yet enforced — the signal endpoint authorizes by workflow ownership only, so the owner can always approve regardless of this list. Delegated-approver enforcement (Telegram binding) is a follow-up; do not rely on this field for security yet.
        - `prompt` string — External-signal flavor — message shown to the approver.
        - `chainEvent` EventTriggerConfig — Fires when matching on-chain events are observed.
          - `queries` EventTriggerQuery[], required
            - `addresses` EthereumAddress[] — Contract addresses to filter events from. Empty matches any contract.
            - `topics` string[] — Topic filters (`topics[0]` is the event signature, `topics[1..]` are indexed parameter values). `null` means wildcard at that position.
            - `maxEventsPerBlock` integer — Safety ceiling per query per block. Exceeded → task cancelled.
            - `contractAbi` unknown[] — Contract ABI entries (JSON form) for event decoding.
              - …
            - `conditions` EventCondition[] — Filters applied to decoded event data.
              - …
            - `methodCalls` EventMethodCall[] — Method calls used to enrich decoded event data (e.g., `decimals`).
              - …
          - `cooldownSeconds` integer — Seconds to wait after a fire before allowing the same task to trigger again. Default 300. 0 disables cooldown.
          - `chainId` integer, required — Numeric chain ID (e.g. 11155111 for Sepolia, 8453 for Base). On chain-aware trigger/node configs this is required and must be a configured chain; on query/filter params it is optional.
        - `timeoutSeconds` integer — Safety bound; 0 = server default (the wait is never unbounded).
  - `inputVariables` InputVariables — Free-form key-value bag of values used to resolve `{{variable.path}}` template references inside trigger and node configs. Conventional well-known keys: `settings.runner` (smart wallet address), `settings.chainId` (chain id). camelCase keys; back-compat support for snake_case keys exists during the migration window.
  - `chainId` integer — Numeric chain ID (e.g. 11155111 for Sepolia, 8453 for Base). On chain-aware trigger/node configs this is required and must be a configured chain; on query/filter params it is optional.
  - `erc20Overrides` ERC20StateOverride[] — Optional ERC20 balance/allowance state overrides applied only during this isolated node simulation. Lets callers seed token balances and approvals so contract-write simulations (e.g. Uniswap swaps) don't revert with "transfer amount exceeds allowance/balance" before the approval/funding transactions have been run. Simulation-only: a real-execution request (isSimulated=false) that sets these is rejected with an error, never silently ignored.
    - `tokenAddress` string, required — Lowercase or checksummed hex EOA / contract address.
    - `ownerAddress` string, required — Lowercase or checksummed hex EOA / contract address.
    - `spenderAddress` string — Lowercase or checksummed hex EOA / contract address.
    - `balance` string — Balance override (hex 0x… or decimal string).
    - `allowance` string — Allowance override (hex 0x… or decimal string).
    - `balanceSlot` integer — Storage slot for the balanceOf mapping. Required when balance is set; ERC20 storage layout varies per token (OpenZeppelin 0, USDC FiatToken 9).
    - `allowanceSlot` integer — Storage slot for the allowance mapping. Required when allowance is set; ERC20 storage layout varies per token (OpenZeppelin 1, USDC FiatToken 10).

## Response `200`

Node execution result.

- RunNodeResponse
  - `success` boolean, required
  - `error` string
  - `errorCode` string
  - `output` unknown
  - `metadata` unknown
  - `executionContext` unknown

## Other responses

- `400` — Request validation failed.
- `401` — Missing or invalid bearer token.

---

[API](https://skmtc.net/avaprotocol/apis/ava-protocol-avs-api.md) · [All operations](https://skmtc.net/avaprotocol/apis/ava-protocol-avs-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/avaprotocol/ava-protocol-avs-api/revisions/caa86e825f53/schema)
