> ## 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.

# Bundling Actions

> Bundle several DeFi actions into a single transaction using the `bundle` API.

The Bundle API is Enso's **multi-action orchestration engine** that executes complex DeFi workflows atomically.

<Tip>
  **Would `route` do the job?** <br />
  The `route` API might be the simpler way to route your assets.
  Before using the bundle API, check if `route` would work using [happypath](https://happypath.enso.build).
</Tip>

While the Route API automatically finds optimal paths between positions, the Bundle API gives you precise control over each action in your sequence - perfect for custom strategies, multi-protocol operations, and advanced DeFi automation.

**Bundle vs Route**: Choose Bundle when you need specific execution order, multi-protocol interactions, or actions beyond simple swaps and deposits. Use Route when you want Enso to handle the optimization automatically.

**Atomic execution**: All actions in a bundle succeed together or revert entirely - no partial executions or stuck funds.

<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" />

## Quick Start

The Bundle API accepts an array of actions that execute sequentially. Each action can use outputs from previous actions, enabling complex workflows impossible with separate transactions.

<Note>
  Bundle supports 15+ action types across 50+ protocols. Common actions include `swap`, `deposit`, `borrow`, `harvest`, and `bridge`. See our [Actions Reference](/pages/build/reference/actions) for the complete list.
</Note>

<Tabs>
  <Tab title="Yield Compounding">
    ```typescript theme={null}
    // Harvest rewards → Swap to base token → Redeposit
    [
      {
        protocol: "curve-gauge",
        action: "harvest",
        args: {
          token: "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0",
          primaryAddress: "0x182B723a58739a9c974cFDB385ceaDb237453c28"
        }
      },
      {
        protocol: "enso",
        action: "route",
        args: {
          tokenIn: "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0",
          tokenOut: "0xae7ab96520de3a18e5e111b5eaab095312d7fe84",
          amountIn: { useOutputOfCallAt: 0 }, // Use harvested amount
          slippage: "300"
        }
      },
      {
        protocol: "curve",
        action: "deposit",
        args: {
          tokenIn: "0xae7ab96520de3a18e5e111b5eaab095312d7fe84",
          tokenOut: "0x06325440d014e39736583c165c2963ba99faf14e",
          amountIn: { useOutputOfCallAt: 1 }, // Use swapped amount
          primaryAddress: "0xDC24316b9AE028F1497c275EB9192a3Ea0f67022"
        }
      }
    ]
    ```
  </Tab>

  <Tab title="Multi-Position Entry">
    ```typescript theme={null}
    // Split 1 ETH across three liquid staking tokens
    [
      {
        protocol: "enso",
        action: "route",
        args: {
          tokenIn: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
          tokenOut: "0xae7ab96520de3a18e5e111b5eaab095312d7fe84", // stETH
          amountIn: "333000000000000000",
          slippage: "100"
        }
      },
      {
        protocol: "enso",
        action: "route",
        args: {
          tokenIn: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
          tokenOut: "0xae78736cd615f374d3085123a210448e74fc6393", // rETH
          amountIn: "333000000000000000",
          slippage: "100"
        }
      },
      {
        protocol: "enso",
        action: "route",
        args: {
          tokenIn: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
          tokenOut: "0xbe9895146f7af43049ca1c1ae358b0541ea49704", // cbETH
          amountIn: "334000000000000000",
          slippage: "100"
        }
      }
    ]
    ```
  </Tab>

  <Tab title="Position Migration">
    ```typescript theme={null}
    // Exit Aave → Enter Compound
    [
      {
        protocol: "aave-v3",
        action: "redeem",
        args: {
          tokenIn: "0x4d5F47FA6A74757f35C14fD3a6Ef8E3C9BC514E8", // aWETH
          tokenOut: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // WETH
          amountIn: "1000000000000000000",
          primaryAddress: "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2"
        }
      },
      {
        protocol: "wrapped-native",
        action: "redeem",
        args: {
          tokenIn: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
          tokenOut: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
          amountIn: { useOutputOfCallAt: 0 },
          primaryAddress: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
        }
      },
      {
        protocol: "compound-v2",
        action: "deposit",
        args: {
          tokenIn: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
          tokenOut: "0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5", // cETH
          amountIn: { useOutputOfCallAt: 1 },
          primaryAddress: "0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5"
        }
      }
    ]
    ```
  </Tab>

  <Tab title="Leverage Loop">
    ```typescript theme={null}
    // Deposit → Borrow → Swap → Redeposit (2x leverage)
    [
      {
        protocol: "aave-v3",
        action: "deposit",
        args: {
          tokenIn: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // WETH
          tokenOut: "0x4d5F47FA6A74757f35C14fD3a6Ef8E3C9BC514E8", // aWETH
          amountIn: "1000000000000000000", // 1 WETH
          primaryAddress: "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2"
        }
      },
      {
        protocol: "aave-v3",
        action: "borrow",
        args: {
          collateral: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
          tokenOut: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // USDC
          amountOut: "2000000000", // 2000 USDC
          primaryAddress: "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2"
        }
      },
      {
        protocol: "enso",
        action: "route",
        args: {
          tokenIn: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
          tokenOut: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
          amountIn: { useOutputOfCallAt: 1 },
          slippage: "100"
        }
      },
      {
        protocol: "aave-v3",
        action: "deposit",
        args: {
          tokenIn: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
          tokenOut: "0x4d5F47FA6A74757f35C14fD3a6Ef8E3C9BC514E8",
          amountIn: { useOutputOfCallAt: 2 },
          primaryAddress: "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2"
        }
      }
    ]
    ```
  </Tab>
</Tabs>

<div className="text-center mt-4">
  <a href="/pages/build/examples/shortcuts" className="text-blue-600 hover:underline">
    Browse 20+ production-ready workflows in our Shortcuts Library →
  </a>
</div>

## Core Concepts

<CardGroup cols={2}>
  <Card title="Action Structure" icon="layer-group">
    Each action requires: `protocol` (where to execute), `action` (what to do), and `args` (action-specific parameters). Actions execute in array order.
  </Card>

  <Card title="Dynamic Outputs" icon="link">
    Use `useOutputOfCallAt` to reference previous action outputs. This enables chaining without knowing amounts in advance - critical for harvesting, compounding, and multi-step strategies.
  </Card>

  <Card title="Atomic Safety" icon="shield-check">
    All actions succeed or all revert. No partial executions, no stuck funds. Failed actions revert the entire bundle, protecting against incomplete workflows.
  </Card>

  <Card title="Gas Efficiency" icon="gas-pump">
    One transaction instead of many. Bundle saves 20-40% on gas compared to separate transactions, plus reduced MEV exposure.
  </Card>
</CardGroup>

<Warning>
  Not all actions work for every protocol! To check which actions are supported per protocol, use the SDK's `getActionsBySlug` ([GET `/v1/actions/{protocol}`](/api-reference/integration/actions-for-protocol)) method.
</Warning>

## Request Structure

Each action in the bundle array follows this structure:

```typescript theme={null}
{
  protocol: string,      // Protocol identifier (e.g., "aave-v3", "uniswap-v2")
  action: string,        // Action type (e.g., "deposit", "swap", "borrow")
  args: {               // Action-specific arguments
    tokenIn?: string,
    tokenOut?: string,
    amountIn?: string | { useOutputOfCallAt: number },
    primaryAddress?: string,
    // ... other protocol-specific args
  }
}
```

**Key parameters:**

* **`primaryAddress`**: Protocol's main contract (pool, vault, router)
* **`useOutputOfCallAt`**: Reference output from action at index N
* **`receiver`**: Optional override for output recipient
* **`slippage`**: Basis points for price protection (100 = 1%)

## Examples

### 0. Install & Authenticate

You can interact with the API using Enso SDK or directly via REST API.

<CodeGroup dropdown>
  ```bash npm theme={null}
  npm i @ensofinance/sdk
  ```

  ```bash pnpm theme={null}
  pnpm i @ensofinance/sdk
  ```

  ```bash yarn theme={null}
  yarn add @ensofinance/sdk
  ```
</CodeGroup>

To use the API, authenticate using your [API key](/pages/build/get-started/authentication).

<CodeGroup dropdown>
  ```typescript SDK theme={null}
  import { EnsoClient } from '@ensofinance/sdk';

  const ensoClient = new EnsoClient({
    apiKey: 'your-api-key-here'
  });
  ```

  ```bash Environment theme={null}
  export ENSO_API_KEY="your-api-key-here"
  ```
</CodeGroup>

### 1. Basic Bundle: Swap and Deposit

Start with a simple two-action bundle that swaps ETH for USDC, then deposits into Aave.
The first action (`route`) will invoke Enso's automatic routing engine and optimize ETH → USDC path,

<Tip>
  This simple example is completely achievable with [DeFi Swap and Routing](/pages/build/get-started/route). This is for illustrative purposes only.
</Tip>

<CodeGroup dropdown>
  ```typescript SDK theme={null}
  const bundle = await ensoClient.getBundleData(
    {
      chainId: 1,
      fromAddress: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      routingStrategy: "delegate"
    },
    [
      // Step 1: Swap ETH to USDC
      {
        protocol: "enso",
        action: "route",
        args: {
          tokenIn: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", // ETH
          tokenOut: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // USDC
          amountIn: "1000000000000000000", // 1 ETH
          slippage: "100" // 1%
        }
      },
      // Step 2: Deposit USDC to Aave (fixed amount)
      {
        protocol: "aave-v3",
        action: "deposit",
        args: {
          tokenIn: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // USDC
          tokenOut: "0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c", // aUSDC
          amountIn: "2000000000", // 2000 USDC
          primaryAddress: "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2"
        }
      }
    ]
  );

  // Execute the bundle
  await wallet.sendTransaction(bundle.tx);
  ```

  ```bash cURL theme={null}
  curl -X POST \
    'https://api.enso.build/api/v1/shortcuts/bundle?chainId=1&fromAddress=0xd8da6bf26964af9d7eed9e03e53415d37aa96045&routingStrategy=delegate' \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $ENSO_API_KEY" \
    -d '[
      {
        "protocol": "enso",
        "action": "route",
        "args": {
          "tokenIn": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
          "tokenOut": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
          "amountIn": "1000000000000000000",
          "slippage": "100"
        }
      },
      {
        "protocol": "aave-v3",
        "action": "deposit",
        "args": {
          "tokenIn": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
          "tokenOut": "0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c",
          "amountIn": "2000000000",
          "primaryAddress": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2"
        }
      }
    ]' | jq
  ```
</CodeGroup>

**What's happening**: This bundle swaps 1 ETH for USDC, then deposits exactly 2000 USDC to Aave. Note the fixed amount in the second action - we'll make this dynamic next.

### 2. Dynamic Chaining: Harvest and Compound

Use `useOutputOfCallAt` to chain actions dynamically.

<CodeGroup dropdown>
  ```typescript SDK theme={null}
  const bundle = await ensoClient.getBundleData(
    {
      chainId: 1,
      fromAddress: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      routingStrategy: "delegate"
    },
    [
        // Step 1: Split 1 ETH into 3 equal portions
        {
          protocol: "enso",
          action: "split",
          args: {
            tokenIn: ETH,
            tokenOut: [ETH, ETH, ETH],
            amountIn: "1000000000000000000", // 1 ETH
            receiver: userAddress,
          },
        },
        // Step 2: Route first portion to stETH
        {
          protocol: "enso",
          action: "route",
          args: {
            tokenIn: ETH,
            tokenOut: stETH,
            amountIn: { useOutputOfCallAt: [0, 0] }, // First output from split
            slippage: "100",
            receiver: userAddress,
          },
        },
        // Step 3: Route second portion to rETH
        {
          protocol: "enso",
          action: "route",
          args: {
            tokenIn: ETH,
            tokenOut: rETH,
            amountIn: { useOutputOfCallAt: [0, 1] }, // Second output from split
            slippage: "100",
            receiver: userAddress,
          },
        },
        // Step 4: Route third portion to cbETH
        {
          protocol: "enso",
          action: "route",
          args: {
            tokenIn: ETH,
            tokenOut: cbETH,
            amountIn: { useOutputOfCallAt: [0, 2] }, // Third output from split
            slippage: "100",
            receiver: userAddress,
          },
        },
      ]
  );

  console.log('Compound tx ready:', bundle.tx);
  ```

  ```bash cURL theme={null}
  curl -X POST \
    'https://api.enso.build/api/v1/shortcuts/bundle?chainId=1&fromAddress=0xd8da6bf26964af9d7eed9e03e53415d37aa96045&routingStrategy=delegate' \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $ENSO_API_KEY" \
    -d '[
      {
        "protocol": "curve-gauge",
        "action": "harvest",
        "args": {
          "token": "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0",
          "primaryAddress": "0x182B723a58739a9c974cFDB385ceaDb237453c28"
        }
      },
      {
        "protocol": "enso",
        "action": "route",
        "args": {
          "tokenIn": "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0",
          "tokenOut": "0xae7ab96520de3a18e5e111b5eaab095312d7fe84",
          "amountIn": { "useOutputOfCallAt": 0 },
          "slippage": "300"
        }
      },
      {
        "protocol": "curve",
        "action": "deposit",
        "args": {
          "tokenIn": "0xae7ab96520de3a18e5e111b5eaab095312d7fe84",
          "tokenOut": "0x06325440d014e39736583c165c2963ba99faf14e",
          "amountIn": { "useOutputOfCallAt": 1 },
          "primaryAddress": "0xDC24316b9AE028F1497c275EB9192a3Ea0f67022"
        }
      }
    ]' | jq
  ```
</CodeGroup>

**Key concept**: `useOutputOfCallAt: 0` references the output from the first action (index 0). This enables compound strategies without knowing reward amounts in advance.

### 4. Leveraged Position

Create a 2x leveraged position by borrowing against deposited collateral.

<CodeGroup dropdown>
  ```typescript SDK theme={null}
  const bundle = await ensoClient.getBundleData(
    {
      chainId: 1,
      fromAddress: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      routingStrategy: "delegate"
    },
    [
      // Deposit WETH as collateral
      {
        protocol: "aave-v3",
        action: "deposit",
        args: {
          tokenIn: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // WETH
          tokenOut: "0x4d5F47FA6A74757f35C14fD3a6Ef8E3C9BC514E8", // aWETH
          amountIn: "1000000000000000000", // 1 WETH
          primaryAddress: "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2"
        }
      },
      // Borrow USDC against WETH
      {
        protocol: "aave-v3",
        action: "borrow",
        args: {
          collateral: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
          tokenOut: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // USDC
          amountOut: "2000000000", // 2000 USDC
          primaryAddress: "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2"
        }
      },
      // Swap borrowed USDC back to WETH
      {
        protocol: "enso",
        action: "route",
        args: {
          tokenIn: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
          tokenOut: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
          amountIn: { useOutputOfCallAt: 1 }, // All borrowed USDC
          slippage: "100"
        }
      },
      // Deposit the additional WETH
      {
        protocol: "aave-v3",
        action: "deposit",
        args: {
          tokenIn: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
          tokenOut: "0x4d5F47FA6A74757f35C14fD3a6Ef8E3C9BC514E8",
          amountIn: { useOutputOfCallAt: 2 }, // All swapped WETH
          primaryAddress: "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2"
        }
      }
    ]
  );

  console.log('2x leveraged WETH position created');
  ```

  ```bash cURL theme={null}
  curl -X POST \
    'https://api.enso.build/api/v1/shortcuts/bundle?chainId=1&fromAddress=0xd8da6bf26964af9d7eed9e03e53415d37aa96045&routingStrategy=delegate' \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $ENSO_API_KEY" \
    -d '[
      {
        "protocol": "aave-v3",
        "action": "deposit",
        "args": {
          "tokenIn": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
          "tokenOut": "0x4d5F47FA6A74757f35C14fD3a6Ef8E3C9BC514E8",
          "amountIn": "1000000000000000000",
          "primaryAddress": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2"
        }
      },
      {
        "protocol": "aave-v3",
        "action": "borrow",
        "args": {
          "collateral": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
          "tokenOut": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
          "amountOut": "2000000000",
          "primaryAddress": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2"
        }
      },
      {
        "protocol": "enso",
        "action": "route",
        "args": {
          "tokenIn": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
          "tokenOut": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
          "amountIn": { "useOutputOfCallAt": 1 },
          "slippage": "100"
        }
      },
      {
        "protocol": "aave-v3",
        "action": "deposit",
        "args": {
          "tokenIn": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
          "tokenOut": "0x4d5F47FA6A74757f35C14fD3a6Ef8E3C9BC514E8",
          "amountIn": { "useOutputOfCallAt": 2 },
          "primaryAddress": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2"
        }
      }
    ]' | jq
  ```
</CodeGroup>

**Leverage mechanics**: Deposit → Borrow → Swap → Redeposit creates leveraged exposure.

### 5. Cross-chain Bundle with Callbacks

Bridge assets and execute actions on the destination chain - all atomically.

<Tip>
  **What's happening**: The `callback` array executes atomically on the destination chain. If any callback action fails, the entire operation (including the bridge) reverts - true cross-chain atomicity!
</Tip>

<CodeGroup dropdown>
  ```typescript SDK theme={null}

  export async function bridgeUsdcAndDepositToAave() {
    const bundle = await client.getBundleData(
      {
        chainId: ETHEREUM_CHAIN_ID,
        fromAddress: USER_ADDRESS,
        routingStrategy: "delegate",
      },
      [
        // Convert USDC to ETH for bridge fee
        {
          protocol: "enso",
          action: "route",
          args: {
            tokenIn: USDC_ETHEREUM,
            tokenOut: ETH_ADDRESS,
            amountIn: USDC_AMOUNT,
            slippage: "100",
          },
        },
        // Bridge ETH to Base with callback actions
        {
          protocol: "stargate",
          action: "bridge",
          args: {
            primaryAddress: STARGATE_PRIMARY_ADDRESS,
            destinationChainId: BASE_CHAIN_ID,
            tokenIn: ETH_ADDRESS,
            amountIn: { useOutputOfCallAt: 0 },
            receiver: USER_ADDRESS,
            // These actions execute on Base after bridging!
            callback: [
              {
                protocol: "enso",
                action: "balance",
                args: {
                  token: ETH_ADDRESS,
                },
              },
              {
                protocol: "enso",
                action: "route",
                args: {
                  tokenIn: ETH_ADDRESS,
                  tokenOut: CBETH_BASE,
                  // amountIn: "10000000000000",
                  amountIn: { useOutputOfCallAt: 0 }, // Use bridged ETH
                  slippage: "200",
                },
              },
              {
                protocol: "aave-v3",
                action: "deposit",
                args: {
                  tokenIn: CBETH_BASE,
                  tokenOut: ACBETH_BASE,
                  amountIn: { useOutputOfCallAt: 1 }, // From the swap above
                  primaryAddress: AAVE_V3_PRIMARY_ADDRESS,
                },
              },
            ],
          },
        },
      ]
    );

    console.log("Cross-chain deposit ready:", bundle.tx);
  }
  // Addresses
  const ETHEREUM_CHAIN_ID = 1;
  const BASE_CHAIN_ID = 8453;

  // User addresses
  const USER_ADDRESS = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045";

  // Token addresses - Ethereum
  const USDC_ETHEREUM = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48";
  const ETH_ADDRESS = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";

  // Token addresses - Base
  const CBETH_BASE = "0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22";
  const ACBETH_BASE = "0xcf3D55c10DB69f28fD1A75Bd73f3D8A2d9c595ad";

  // Protocol addresses
  const STARGATE_PRIMARY_ADDRESS = "0x77b2043768d28e9c9ab44e1abfc95944bce57931";
  const AAVE_V3_PRIMARY_ADDRESS = "0xA238Dd80C259a72e81d7e4664a9801593F98d1c5";

  // Amounts
  const USDC_AMOUNT = "3000000000"; // 3000 USDC
  ```

  ```bash cURL theme={null}
  curl -X POST \
    'https://api.enso.build/api/v1/shortcuts/bundle?chainId=1&fromAddress=0xd8da6bf26964af9d7eed9e03e53415d37aa96045&routingStrategy=delegate' \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $ENSO_API_KEY" \
    -d '[
      {
        "protocol": "enso",
        "action": "route",
        "args": {
          "tokenIn": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
          "tokenOut": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
          "amountIn": "3000000000",
          "slippage": "100"
        }
      },
      {
        "protocol": "stargate",
        "action": "bridge",
        "args": {
          "primaryAddress": "0x77b2043768d28e9c9ab44e1abfc95944bce57931",
          "destinationChainId": 8453,
          "tokenIn": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
          "amountIn": { "useOutputOfCallAt": 0 },
          "receiver": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
          "callback": [
            {
              "protocol": "enso",
              "action": "route",
              "args": {
                "tokenIn": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
                "tokenOut": "0x2Ae3F1Ec7F328C4243D5eE",
                "amountIn": { "useOutputOfCallAt": 0 },
                "slippage": "200"
              }
            },
            {
              "protocol": "aave-v3",
              "action": "deposit",
              "args": {
                "tokenIn": "0x2Ae3F1Ec7F328C4243D5eE",
                "tokenOut": "0x078f358208685046a11C85e8ad32895DED33A249",
                "amountIn": { "useOutputOfCallAt": 0 },
                "primaryAddress": "0xA238Dd80C259a72e81d7e4664a9801593F98d1c5"
              }
            }
          ]
        }
      }
    ]' | jq
  ```
</CodeGroup>

## Utility Actions

Bundle API includes helper actions for safety and flow control:

<CardGroup cols={2}>
  <Card title="Balance Check" icon="scale-balanced">
    Get token balance mid-bundle. Supports [advanced options](/pages/build/reference/balance) for external accounts and estimated amounts.

    ```json theme={null}
    {
      "protocol": "enso",
      "action": "balance",
      "args": {
        "token": "0xa0b8...b48"
      }
    }
    ```
  </Card>

  <Card title="Slippage Protection" icon="shield">
    Apply slippage to any output:

    ```json theme={null}
    {
      "protocol": "enso",
      "action": "slippage",
      "args": {
        "amountOut": { "useOutputOfCallAt": 0 },
        "bps": "100"
      }
    }
    ```
  </Card>

  <Card title="Minimum Output" icon="greater-than-equal">
    Enforce minimum amounts:

    ```json theme={null}
    {
      "protocol": "enso",
      "action": "minAmountOut",
      "args": {
        "amountOut": { "useOutputOfCallAt": 0 },
        "minAmountOut": "1000000000"
      }
    }
    ```
  </Card>

  <Card title="Fee Collection" icon="percent">
    Take protocol fees:

    ```json theme={null}
    {
      "protocol": "enso",
      "action": "fee",
      "args": {
        "token": "0xeee...eee",
        "amount": { "useOutputOfCallAt": 0 },
        "bps": "250",
        "receiver": "0xfee...add"
      }
    }
    ```
  </Card>

  <Card title="Math Operations" icon="calculator">
    Perform on-chain arithmetic (`add`, `sub`, `mul`, `div`, `min`, `max`):

    ```json theme={null}
    {
      "protocol": "math",
      "action": "div",
      "args": {
        "amountA": { "useOutputOfCallAt": 0 },
        "amountB": "2"
      }
    }
    ```
  </Card>

  <Card title="Conditional Logic" icon="code-branch">
    Compare values and assert conditions (`isequal`, `isgreaterthan`, `check`, `toggle`, etc.):

    ```json theme={null}
    {
      "protocol": "helpers",
      "action": "check",
      "args": {
        "condition": { "useOutputOfCallAt": 1 }
      }
    }
    ```
  </Card>
</CardGroup>

## Next Steps

From here, you can explore other resources:

* **[Actions Reference](/pages/build/reference/actions)**: Complete list of supported actions and protocols
* **[Routing Strategies](/pages/build/reference/routing-strategies)**: Overview of `delegate` and `router` strategies for action execution\*\*.\*\*
* **[Shortcuts Library](/pages/build/examples/shortcuts)**: 20+ production-ready bundle examples
* **[Route API](/pages/build/get-started/route)**: When automatic routing is better than custom bundles

<LastUpdated date="2025-09-30" />
