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

# Bundle API

> Compose ordered public actions into a signer-ready transaction with the Bundle API.

The Bundle API builds one transaction from an ordered array of actions selected by your product. Use it for custom sequencing, dynamic outputs, checks, fees, flashloans, or protocol actions that do not fit a single Route API request.

<Note>
  If Enso should choose the entire path into one destination, start with the [Route API](/pages/build/get-started/route). See [Route API vs Bundle API](/pages/build/get-started/overview#route-api-vs-bundle-api) before building a custom sequence.
</Note>

Actions executed in one same-chain transaction succeed or revert together. Cross-chain delivery is different: the source transaction completes first, then the callback executes on the destination chain. A destination callback failure cannot revert a finalized source-chain bridge.

<img src="https://mintcdn.com/enso/nu8qK2z1ysTh8AfC/images/bundle-dark.webp?fit=max&auto=format&n=nu8qK2z1ysTh8AfC&q=85&s=74d9edf9f4973f46ed5d5f728bb4f564" className="hidden dark:block" width="800" height="528" data-path="images/bundle-dark.webp" />

<img src="https://mintcdn.com/enso/nu8qK2z1ysTh8AfC/images/bundle-light.webp?fit=max&auto=format&n=nu8qK2z1ysTh8AfC&q=85&s=cc19b38b72b5d721af3ea13695926df3" className="dark:hidden" width="800" height="528" data-path="images/bundle-light.webp" />

## Before you start

1. [Create and verify an API key](/pages/build/get-started/authentication).
2. Choose a supported chain, protocol, and public action.
3. Use the [Bundle Actions Reference](/pages/build/reference/actions) for action inputs and outputs.
4. Use [supported actions](/api-reference/integration/supported-actions) and the per-protocol action endpoint for current protocol availability.

## Request anatomy

```http theme={null}
POST /api/v1/shortcuts/bundle?chainId=1&fromAddress=0x...&routingStrategy=router
Authorization: Bearer $ENSO_API_KEY
Content-Type: application/json
```

The request body is the action array directly:

```json theme={null}
[
  {
    "protocol": "enso",
    "action": "route",
    "args": {
      "tokenIn": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
      "tokenOut": "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
      "amountIn": "100000000000",
      "slippage": "300"
    }
  }
]
```

Do not wrap the array in `{ "bundle": [...] }`. Wallet and execution settings belong in query parameters for REST, or in the first argument to `getBundleData` in the SDK.

### Request options

| Field               | Required | Description                                                             |
| ------------------- | -------- | ----------------------------------------------------------------------- |
| `chainId`           | Yes      | Source-chain ID.                                                        |
| `fromAddress`       | Yes      | Wallet that submits the returned transaction.                           |
| `routingStrategy`   | No       | Execution client strategy.                                              |
| `executionMode`     | No       | Quote execution mode.                                                   |
| `receiver`          | No       | Default recipient for final outputs.                                    |
| `spender`           | No       | Account supplying input assets when supported by the selected strategy. |
| `refundReceiver`    | No       | Recipient for dust or applicable bridge refunds.                        |
| `ignoreAggregators` | No       | Swap aggregators to exclude globally.                                   |
| `skipQuote`         | No       | Skip quote-dependent output and gas fields.                             |
| `referralCode`      | No       | Referral code included in the on-chain event.                           |

## Action structure

Every action has three fields:

```typescript theme={null}
{
  protocol: "enso",
  action: "route",
  args: {
    tokenIn: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
    tokenOut: "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
    amountIn: "100000000000",
  },
}
```

* `protocol` selects the Enso meta-action or protocol integration.
* `action` selects a public action supported by that protocol.
* `args` contains the action-specific inputs.

Protocol action inputs are not universal. Query the current per-protocol action metadata instead of assuming every `deposit`, `redeem`, or `swap` accepts the same fields.

## Amounts and native assets

Use decimal strings in the token's smallest base unit. Do not use JavaScript numbers for token amounts.

* `"1000000"` is 1 USDC when the token has 6 decimals.
* `"1000000000000000000"` is 1 ETH or one 18-decimal token.
* Use `0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee` for the native asset.

When native value is involved, send the returned `tx.value` exactly as provided.

## Chain action outputs

A later action can consume an earlier action's output:

```typescript theme={null}
{ useOutputOfCallAt: 0 }
```

If the producer returns an array, select an item explicitly:

```typescript theme={null}
{ useOutputOfCallAt: 0, index: 1 }
```

References are zero-based and must point to an earlier output. Array outputs require `index`. Some checks do not expose a normal consumable output; consult the [action output table](/pages/build/reference/actions#action-outputs) before chaining them.

## Receivers and intermediate assets

The query-level `receiver` is the default recipient for final outputs. An action-level `receiver` overrides recipient behavior for that action when supported. `refundReceiver` is for dust or applicable cross-chain refunds.

Do not send every intermediate output to the user. Assets consumed by later actions must remain with the executing account until the sequence completes.

## Example: route into a deposit

This source-backed example routes native ETH into rETH and deposits the route output into Aave. The deposit consumes action `0` dynamically.

```typescript theme={null}
import { EnsoClient } from "@ensofinance/sdk";

const client = new EnsoClient({ apiKey: process.env.ENSO_API_KEY! });

const result = await client.getBundleData(
  {
    chainId: 1,
    fromAddress: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
    routingStrategy: "router",
  },
  [
    {
      protocol: "enso",
      action: "route",
      args: {
        tokenIn: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
        tokenOut: "0xae78736Cd615f374D3085123A210448E74Fc6393",
        amountIn: "10000000000000000",
        slippage: "300",
      },
    },
    {
      protocol: "aave-v3",
      action: "deposit",
      args: {
        primaryAddress: "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2",
        tokenIn: "0xae78736Cd615f374D3085123A210448E74Fc6393",
        tokenOut: "0xCc9EE9483f662091a1de4795249E24aC0aC2630f",
        amountIn: { useOutputOfCallAt: 0 },
      },
    },
  ],
);
```

Equivalent REST request:

```bash theme={null}
curl --fail --silent --show-error -X POST \
  'https://api.enso.build/api/v1/shortcuts/bundle?chainId=1&fromAddress=0xd8da6bf26964af9d7eed9e03e53415d37aa96045&routingStrategy=router' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ENSO_API_KEY" \
  -d '[
    {
      "protocol": "enso",
      "action": "route",
      "args": {
        "tokenIn": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
        "tokenOut": "0xae78736Cd615f374D3085123A210448E74Fc6393",
        "amountIn": "10000000000000000",
        "slippage": "300"
      }
    },
    {
      "protocol": "aave-v3",
      "action": "deposit",
      "args": {
        "primaryAddress": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2",
        "tokenIn": "0xae78736Cd615f374D3085123A210448E74Fc6393",
        "tokenOut": "0xCc9EE9483f662091a1de4795249E24aC0aC2630f",
        "amountIn": { "useOutputOfCallAt": 0 }
      }
    }
  ]' | jq
```

## Example: consume an array output

`split` returns one output per `tokenOut`. The following CLMM deposit selects both outputs explicitly.

```typescript theme={null}
const result = await client.getBundleData(
  {
    chainId: 42161,
    fromAddress: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
    routingStrategy: "router",
  },
  [
    {
      protocol: "enso",
      action: "split",
      args: {
        tokenIn: "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9",
        tokenOut: [
          "0xaf88d065e77c8cc2239327c5edb3a432268e5831",
          "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9",
        ],
        amountIn: "100000000",
      },
    },
    {
      protocol: "sushiswap-v3",
      action: "depositclmm",
      args: {
        tokenOut: "0xf0cbce1942a68beb3d1b73f0dd86c8dcc363ef49",
        ticks: [-887271, 887271],
        tokenIn: [
          "0xaf88d065e77c8cc2239327c5edb3a432268e5831",
          "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9",
        ],
        poolFee: "100",
        amountIn: [
          { useOutputOfCallAt: 0, index: 0 },
          { useOutputOfCallAt: 0, index: 1 },
        ],
      },
    },
  ],
);
```

For CLMM flows that require explicit protection for the internal swaps, `slippage` checks can sit between `split` and `depositclmm`. They reference the split outputs; they do not need to appear after the final deposit.

## Example: route fee

Route fees are deducted from the corresponding input amounts before routing. `fee` is an array aligned with `amountIn`; `"100"` is 1%.

```typescript theme={null}
{
  protocol: "enso",
  action: "route",
  args: {
    tokenIn: "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
    tokenOut: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    amountIn: { useOutputOfCallAt: 0 },
    fee: ["100"],
    feeReceiver: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
    slippage: "1000",
  },
}
```

For a standalone fee step that returns the net amount, use the public [`enso:fee` action](/pages/build/reference/actions#fee).

## Example: bridge callback

A bridge callback executes later on the destination chain. For supported callback bridges, the callback must begin with `enso:balance`; callback output references are local to the callback array.

```typescript theme={null}
const result = await client.getBundleData(
  {
    chainId: 10,
    fromAddress: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
    receiver: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
    routingStrategy: "router",
  },
  [
    {
      protocol: "stargate",
      action: "bridge",
      args: {
        primaryAddress: "0xe8cdf27acd73a434d661c84887215f7598e7d0d3",
        destinationChainId: 130,
        tokenIn: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
        amountIn: "5000000000000000000",
        receiver: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
        callback: [
          {
            protocol: "enso",
            action: "balance",
            args: {
              token: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
            },
          },
          {
            protocol: "enso",
            action: "route",
            args: {
              tokenIn: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
              tokenOut: "0x078d782b760474a361dda0af3839290b0ef57ad6",
              amountIn: { useOutputOfCallAt: 0 },
              slippage: "100",
            },
          },
        ],
      },
    },
  ],
);
```

After submitting the source transaction, monitor [Bridge Status](/pages/build/get-started/bridge-status). Bridge-provider callback capabilities and refund behavior differ; see [Crosschain Routing](/pages/build/get-started/crosschain-routing).

## Execute the response

Building a bundle does not submit it.

1. Inspect `approvals`. Submit each required approval transaction before the bundle transaction.
2. Submit `tx` unchanged, including `to`, `data`, and `value`.
3. Do not submit an expired quote; respect `validUntil` when present.
4. For cross-chain bundles, monitor bridge and destination status after source confirmation.

### Response fields

| Field               | Description                                                                              |
| ------------------- | ---------------------------------------------------------------------------------------- |
| `tx`                | Signer-ready transaction.                                                                |
| `approvals`         | External approval transactions required before `tx`.                                     |
| `createdAt`         | Block number used to build the transaction.                                              |
| `bundle`            | Normalized action sequence returned by the backend. It can include injected fee actions. |
| `route`             | Expanded route hops selected for route actions.                                          |
| `amountsOut`        | Expected final outputs by token.                                                         |
| `minAmountsOut`     | Minimum protected outputs by token.                                                      |
| `feeAmount`         | Fees by token.                                                                           |
| `gas`               | Estimated gas when quoting is enabled.                                                   |
| `priceImpact`       | Estimated price impact when available.                                                   |
| `bridgingEstimates` | Cross-chain timing and fee estimates when applicable.                                    |
| `validUntil`        | Quote expiry timestamp when applicable.                                                  |
| `userOp`            | ERC-4337 user operation for supported execution flows.                                   |

When `skipQuote=true`, quote-dependent fields such as output amounts and gas may be absent.

## Limits and common errors

| Constraint                        | Current limit or behavior                                                                                                            |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| Top-level actions                 | 50 maximum                                                                                                                           |
| Total actions including callbacks | 100 maximum                                                                                                                          |
| Actions in each callback          | 10 maximum                                                                                                                           |
| Callback nesting                  | 5 callback levels beneath a top-level action                                                                                         |
| Output references                 | Resolved against outputs already built; missing or future references fail during bundle construction. Array outputs require `index`. |
| Static `amountIn`                 | Positive base-unit integer string; placeholders and output references are also supported. Other amount fields are action-specific.   |
| Callback order                    | CCIP, Stargate, and Relay callbacks require `enso:balance` first. CCTP callbacks support a narrower documented sequence.             |
| Simulation failure                | Error detail depends on the failing action and simulation path; detailed simulation context is not guaranteed.                       |

See the [FAQ](/pages/build/reference/faq) and [Bundle Actions Reference](/pages/build/reference/actions) for action-specific constraints.

## Next steps

<CardGroup cols={2}>
  <Card title="Bundle Actions Reference" icon="list" href="/pages/build/reference/actions">
    Review public action inputs, outputs, fees, checks, and composition rules.
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/defi-shortcuts/bundle-a-list-of-actions">
    Inspect the exact Bundle endpoint request and response schema.
  </Card>

  <Card title="Routing Strategies" icon="route" href="/pages/build/reference/routing-strategies">
    Understand execution-account and approval behavior.
  </Card>

  <Card title="Crosschain Routing" icon="bridge" href="/pages/build/get-started/crosschain-routing">
    Choose bridge protocols and monitor asynchronous destination execution.
  </Card>
</CardGroup>
