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

> ## Agent Instructions
> These are the Ampli Intelligence docs. API base: https://si.ampli.net/api/v1. API MCP: https://si.ampli.net/mcp.
> Auth is a partner key (X-Partner-Name and X-Partner-API-Key headers) or an x402 payment in USDC on Base.
> For a single-treasury agentic wallet or Wallet-as-a-Service, use the ampli^ SDK at https://ampli.net and https://docs.ampli.net. agk_ keys and /api/v1/agent-runtime belong to that SDK.
> Use only the routes and tools documented here. Do not invent endpoints or parameters.
> The ampli^ SDK (https://ampli.net, docs at https://docs.ampli.net) can use this intelligence to deliver a single-treasury agentic wallet or Wallet-as-a-Service. This host is si.ampli.net. Auth is a partner key or an x402 payment. agk_ keys and /api/v1/agent-runtime belong to the SDK Agent API.
> Every amount is an integer string in the token's base units. USDC, EURC, USDT0, and USDG use 6 decimals (1000000 is 1 USDC). WETH and cbETH use 18. cbBTC uses 8.
> The service is non-custodial. It returns an allocation, an action plan, and calldata. It never holds keys, signs, or sends a transaction.
> APR values are percentages measured now or over the trailing 7 days. They are not forecasts and nothing here guarantees a return.
> x402 payments are verified before the work and settled only when the response is 2xx. A 400 or 422 costs nothing.
> Partner headers always win. A request with a wrong partner key returns 401 and does not fall back to payment.
> Monitor alerts arrive only on the websocket. create_monitor_session returns a token; the client must open the socket itself.
> Market names in optimize must come from list_protocols for the same chain and token. Do not guess names.

# Optimize

> POST /optimizer/{chain_id}/optimize returns the target allocation, an ordered action plan, and ready-to-sign calldata for one token on one chain.

```http theme={null}
POST https://si.ampli.net/api/v1/optimizer/{chain_id}/optimize
```

Priced per call with x402, or free with partner headers. MCP tool: `optimize`.

## Request

| Field | Type | Required | Meaning |
| :- | :- | :- | :- |
| `total_capital` | integer string | yes | Everything to place, in base units. Must be positive |
| `token_address` | address | yes | The underlying token, for example USDC on Base |
| `current_allocations` | object | yes | Market name to amount held now, in base units. Use `{}` for a fresh deposit |
| `protocols` | string array | yes | Market names the plan may use. Take them from the [market list](https://docs.si.ampli.net/markets.md) |
| `constraints` | array | no | Your policy limits. See [caller constraints](https://docs.si.ampli.net/risk-rules.md#caller-constraints) |
| `wallet_address` | address | no | The wallet that will sign. Deposits are made out to it and withdrawals come from it. Send it whenever you plan to execute the calldata |

`current_allocations` may sum to less than `total_capital`; the rest is idle cash to deploy. A sum above `total_capital` returns `422`.

```json theme={null}
{
  "total_capital": "1000000000",
  "token_address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  "current_allocations": { "aave": "500000000", "compound": "500000000" },
  "protocols": ["aave", "compound", "moonwell", "fluid", "euler_usdc", "spark", "superform"],
  "constraints": [
    { "kind": "max_amount_per_protocol", "params": { "protocol": "superform", "max_ratio": 0.6 } }
  ],
  "wallet_address": "0xYourWallet"
}
```

This request holds 500 USDC (`500000000`) in Aave and 500 USDC in Compound, and caps Superform at 60% of the 1,000 USDC total.

## Response

```json theme={null}
{
  "optimization_result": {
    "allocations": [
      { "protocol": "superform", "allocation": "600000000", "apr": 6.22 },
      { "protocol": "moonwell", "allocation": "400000000", "apr": 5.10 },
      { "protocol": "aave", "allocation": "0", "apr": 3.80 }
    ],
    "total_costs": 14019.28,
    "weighted_apr_initial": 3.90,
    "weighted_apr_final": 5.77,
    "apr_improvement": 47.95,
    "gas_estimate_usd": 0.014,
    "break_even_days": 0.22
  },
  "action_plan": [
    { "action_type": "withdraw", "protocol": "compound", "amount": "500000000" },
    { "action_type": "withdraw", "protocol": "aave", "amount": "500000000" },
    { "action_type": "deposit", "protocol": "superform", "amount": "600000000" },
    { "action_type": "deposit", "protocol": "moonwell", "amount": "400000000" }
  ],
  "calldata": [
    {
      "contract_address": "0xb125E6687d4313864e53df431d5425969c15Eb2F",
      "function_name": "withdraw",
      "parameters": ["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "500000000"],
      "value": "0",
      "protocol": "compound",
      "description": "Withdraw 500000000 from compound"
    }
  ],
  "market_rules": [
    { "protocol": "superform", "eligible": true, "max_allocation": null, "apr_scale": null, "reasons": [] },
    {
      "protocol": "moonwell",
      "eligible": true,
      "max_allocation": "400000000",
      "apr_scale": null,
      "reasons": ["new position limited to 60% of withdrawable liquidity"]
    },
    {
      "protocol": "compound",
      "eligible": false,
      "max_allocation": null,
      "apr_scale": null,
      "reasons": ["utilization 97.1% above 95%"]
    }
  ]
}
```

Values are illustrative and shortened. Live APRs change every block.

| Field | Meaning |
| :- | :- |
| `allocations[].allocation` | Target holding per market, in base units. `600000000` is 600 USDC |
| `allocations[].apr` | Expected APR at that size, in percent. `6.22` means 6.22% |
| `total_costs` | Gas for the whole plan, in the token's base units. `14019.28` is about 0.014 USDC |
| `gas_estimate_usd` | The same gas in US dollars |
| `weighted_apr_initial`, `weighted_apr_final` | Blended APR of the book before and after, in percent |
| `apr_improvement` | Relative change between the two, in percent |
| `break_even_days` | Days of extra yield needed to pay back the gas |
| `action_plan` | Moves in execution order. Withdrawals come first so deposits are funded |
| `calldata` | One transaction per entry, in order: `approve` and `deposit` for new positions, `withdraw` or `redeem` for exits |
| `market_rules[]` | One entry per requested market, explaining what the [risk rules](https://docs.si.ampli.net/risk-rules.md) did to it in this run |
| `market_rules[].eligible` | `false` when the market is closed to new deposits. A closed market is never force-exited |
| `market_rules[].max_allocation` | The most the market may hold, in base units. `null` when no rule caps it below `total_capital` |
| `market_rules[].apr_scale` | Multiplier applied to the APR curve when the latest APR is above its 7-day mean. `null` when unscaled |
| `market_rules[].reasons` | The rules that applied, in plain words, for example `utilization 97.1% above 95%` |

> [!NOTE]
>
> APR figures are measurements and model outputs at the time of the call, not promises. A rate can move between the call and execution, and a plan is never risk-free.

## How the plan is built

**1. Read the markets**

For every requested market the service reads supply, borrows, withdrawable liquidity, and utilization on-chain, plus Morpho risk warnings and the largest depositor for Morpho vaults, and the trailing 7-day APR.

**2. Build a yield curve**

A deposit lowers the rate it earns. Each market's own rate model is asked what it would pay after deposits from zero up to the full amount. Below 10,000 USDC a deposit barely moves any rate, so the spot APR is used.

**3. Apply the rules**

The [risk rules](https://docs.si.ampli.net/risk-rules.md) and your constraints become caps and floors per market. Markets that cannot take new money and hold nothing are dropped.

**4. Price gas and solve**

Gas for each move is spread over a 30-day horizon, so a move whose extra yield does not cover its gas in that window is not made. The split is solved as a mixed-integer linear program.

**5. Plan and encode**

The difference between current and target holdings becomes the action plan, then calldata with your wallet as receiver.

## When the full amount does not fit

If the rules leave less room than `total_capital`, the call returns `400` and the detail says how much can be placed (the insufficient capacity case). Lower `total_capital`, add markets, or relax a constraint. The service never returns a partial plan that strands funds. See [Errors](https://docs.si.ampli.net/errors.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.