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

# Portfolio Analysis API

> Analyze instruments, score allocations, compare portfolio changes, and simulate historical yield

## Overview

The Portfolio Analysis API provides stateless analysis tools for yield portfolio construction. Use it to inspect a single instrument, score a weighted allocation book, compare two books, or simulate historical compounded yield at fixed weights.

All endpoints are under the global `/api/v1` prefix and use `x-api-key` authentication.

<Note>
  Portfolio analysis APY values are returned as percentages. For example, `5.2` means `5.2%` APY.
</Note>

<Warning>
  These endpoints describe yield history and concentration. They do not model depeg risk, protocol failure, principal loss, gas, bridge costs, or future APY changes.
</Warning>

## Allocation Format

Portfolio endpoints accept allocations as instrument IDs with weights in basis points.

```json theme={null}
{
  "allocations": [
    {
      "instrumentId": "0x00002105c053a3e1290845e12a3eea14926472ce7f15da324cdf0700056fc04b",
      "weightBps": 6000
    },
    {
      "instrumentId": "0x00002105e1d832a44e229e784c3d4afba9a1ca44a288e34f7e5ddcba23155adc",
      "weightBps": 4000
    }
  ]
}
```

Weights should normally sum to `10000`. If some instruments cannot be resolved, the backend excludes them, returns a warning, and normalizes over the resolved positions.

## Analyze Instrument

<span style={{color: '#10B981', fontWeight: 'bold'}}>GET</span> `/instruments/:instrumentId/analysis`

Return a per-instrument analyst card with current yield, APY stability, liquidity, price-risk flag, and data-derived tier.

### Request

```bash theme={null}
curl -H "x-api-key: your-api-key" \
  "https://api.1tx.fi/api/v1/instruments/0x00002105c053a3e1290845e12a3eea14926472ce7f15da324cdf0700056fc04b/analysis"
```

### Path Parameters

| Parameter      | Type   | Required | Description                          |
| -------------- | ------ | -------- | ------------------------------------ |
| `instrumentId` | string | Yes      | Public instrument ID, as bytes32 hex |

### Response

```json theme={null}
{
  "instrumentId": "0x00002105c053a3e1290845e12a3eea14926472ce7f15da324cdf0700056fc04b",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Aave V3 USDC lending pool on Base",
  "protocol": "Aave",
  "chainId": 8453,
  "yield": {
    "currentApyPct": 5.2,
    "apyMean30dPct": 5.05,
    "rewardSharePct": 3.85
  },
  "stability": {
    "coefficientOfVariation": 0.12,
    "yieldDrawdownPct": 0.42,
    "downsideFreqPct": 6.67,
    "trendPctPerWeek": 0.04,
    "historyDays": 180
  },
  "liquidity": {
    "tvlUsd": 1250000000,
    "lowLiquidity": false
  },
  "priceRisk": false,
  "tier": "Core",
  "headline": "Aave V3 USDC lending pool on Base: 5.2% APY, Core tier, CV 0.12 over 180d, 4% reward-driven.",
  "caveats": [
    "APY mean-reverts and incentive APY decays; high current APY is not durable yield."
  ]
}
```

### Key Response Fields

| Field                              | Type      | Description                                                                   |
| ---------------------------------- | --------- | ----------------------------------------------------------------------------- |
| `yield.currentApyPct`              | number    | Latest instrument APY, as a percentage                                        |
| `yield.apyMean30dPct`              | number    | Current 30-day mean APY from synced metrics                                   |
| `yield.rewardSharePct`             | number    | Share of current APY driven by rewards, as a percentage                       |
| `stability.coefficientOfVariation` | number    | APY standard deviation divided by mean; lower is steadier                     |
| `stability.yieldDrawdownPct`       | number    | Worst peak-to-trough drop in APY over the lookback window                     |
| `stability.downsideFreqPct`        | number    | Percent of days below the configured downside APY target                      |
| `stability.trendPctPerWeek`        | number    | Recent APY trend in percentage points per week                                |
| `liquidity.lowLiquidity`           | boolean   | `true` when TVL is below the configured low-liquidity floor                   |
| `priceRisk`                        | boolean   | `true` for instruments whose NAV can fall, such as non-stablecoin instruments |
| `tier`                             | string    | Data-derived tier: `Core`, `Yield`, or `Frontier`                             |
| `headline`                         | string    | One-line summary of the analysis                                              |
| `caveats`                          | string\[] | Risk and methodology caveats that should be shown to users                    |

***

## Analyze Portfolio

<span style={{color: '#3B82F6', fontWeight: 'bold'}}>POST</span> `/portfolios/analyze`

Score a weighted allocation book across yield, stability, diversification, concentration, structural tail risk, and tier sleeves.

### Request

```bash theme={null}
curl -X POST "https://api.1tx.fi/api/v1/portfolios/analyze" \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "allocations": [
      {
        "instrumentId": "0x00002105c053a3e1290845e12a3eea14926472ce7f15da324cdf0700056fc04b",
        "weightBps": 6000
      },
      {
        "instrumentId": "0x00002105e1d832a44e229e784c3d4afba9a1ca44a288e34f7e5ddcba23155adc",
        "weightBps": 4000
      }
    ]
  }'
```

### Request Body

| Field                        | Type   | Required | Description                                            |
| ---------------------------- | ------ | -------- | ------------------------------------------------------ |
| `allocations`                | array  | Yes      | One or more allocation objects                         |
| `allocations[].instrumentId` | string | Yes      | Public instrument ID, as bytes32 hex                   |
| `allocations[].weightBps`    | number | Yes      | Allocation weight in basis points, from `0` to `10000` |

### Response

```json theme={null}
{
  "resolvedCount": 2,
  "warnings": [],
  "yield": {
    "netApyPct": 5.04,
    "grossApyPct": 5.04,
    "weightedApyMean30dPct": 4.91
  },
  "stability": {
    "coefficientOfVariation": 0.14,
    "yieldDrawdownPct": 0.51,
    "daysWithinBandPct": 88.33,
    "coveragePct": 100
  },
  "diversification": {
    "effectivePositions": 1.92,
    "effectiveIndependentBets": 1.74,
    "avgPairwiseCorrelation": 0.21,
    "coverageBps": 10000
  },
  "concentration": {
    "effectivePositions": 1.92,
    "hhi": 0.52,
    "topWeightBps": 6000,
    "byProtocol": {
      "items": [
        { "key": "Aave", "weightBps": 6000 },
        { "key": "Morpho", "weightBps": 4000 }
      ],
      "effectiveGroups": 1.92,
      "topWeightBps": 6000
    },
    "byChain": {
      "items": [{ "key": "Base", "weightBps": 10000 }],
      "effectiveGroups": 1,
      "topWeightBps": 10000
    },
    "byAssetCategory": {
      "items": [{ "key": "USD", "weightBps": 10000 }],
      "effectiveGroups": 1,
      "topWeightBps": 10000
    },
    "byUnderlying": {
      "items": [{ "key": "USDC", "weightBps": 10000 }],
      "effectiveGroups": 1,
      "topWeightBps": 10000
    },
    "limitFlags": []
  },
  "tail": {
    "oneFailureCostBps": 6000,
    "sleeveWipeBps": 10000,
    "worstProtocolBps": 6000,
    "worstAssetCategoryBps": 10000,
    "weightedRewardSharePct": 4.6,
    "liquidity": {
      "weightedTvlUsd": 884000000,
      "illiquidWeightBps": 0
    }
  },
  "tranches": [
    {
      "name": "Core",
      "instrumentIds": [
        "0x00002105c053a3e1290845e12a3eea14926472ce7f15da324cdf0700056fc04b"
      ],
      "weightBps": 6000,
      "netApyPct": 5.2,
      "stabilityCV": 0.12,
      "rationale": "High TVL, low yield variability, and low reward dependence."
    }
  ],
  "headline": "2 positions at 5.04% blended APY, behaving like ~1.74 independent bets.",
  "caveats": [
    "netApy is currently gross; no gas / bridge / fee model yet."
  ]
}
```

### Key Response Fields

| Field                                      | Type           | Description                                                                            |
| ------------------------------------------ | -------------- | -------------------------------------------------------------------------------------- |
| `resolvedCount`                            | number         | Number of requested instruments found and scored                                       |
| `warnings`                                 | string\[]      | Missing instruments or low-confidence analysis warnings                                |
| `yield.netApyPct`                          | number         | Weighted portfolio APY, currently gross of costs                                       |
| `stability.coefficientOfVariation`         | number         | CV of the blended portfolio APY series                                                 |
| `stability.coveragePct`                    | number         | Percent of blended-history days with enough data coverage                              |
| `diversification.effectivePositions`       | number         | Inverse-Herfindahl effective number of positions                                       |
| `diversification.effectiveIndependentBets` | number \| null | Correlation-adjusted effective bets, or `null` when history is thin                    |
| `concentration.limitFlags`                 | array          | Concentration cap breaches by position, protocol, chain, asset category, or underlying |
| `tail.oneFailureCostBps`                   | number         | Worst single-position failure exposure in basis points                                 |
| `tail.weightedRewardSharePct`              | number         | Weighted share of APY from incentives                                                  |
| `tranches`                                 | array          | Portfolio sleeves grouped by `Core`, `Yield`, and `Frontier` tiers                     |
| `headline`                                 | string         | One-line summary of the scorecard                                                      |
| `caveats`                                  | string\[]      | Risk and methodology caveats that should be shown to users                             |

***

## Compare Allocations

<span style={{color: '#3B82F6', fontWeight: 'bold'}}>POST</span> `/portfolios/compare`

Compare two allocation books and return before/after analyses with metric and factor-exposure deltas.

### Request

```bash theme={null}
curl -X POST "https://api.1tx.fi/api/v1/portfolios/compare" \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "before": [
      {
        "instrumentId": "0x00002105c053a3e1290845e12a3eea14926472ce7f15da324cdf0700056fc04b",
        "weightBps": 10000
      }
    ],
    "after": [
      {
        "instrumentId": "0x00002105c053a3e1290845e12a3eea14926472ce7f15da324cdf0700056fc04b",
        "weightBps": 6000
      },
      {
        "instrumentId": "0x00002105e1d832a44e229e784c3d4afba9a1ca44a288e34f7e5ddcba23155adc",
        "weightBps": 4000
      }
    ]
  }'
```

### Request Body

| Field                                            | Type   | Required | Description                                |
| ------------------------------------------------ | ------ | -------- | ------------------------------------------ |
| `before`                                         | array  | Yes      | Allocation book before the proposed change |
| `after`                                          | array  | Yes      | Allocation book after the proposed change  |
| `before[].instrumentId` / `after[].instrumentId` | string | Yes      | Public instrument ID, as bytes32 hex       |
| `before[].weightBps` / `after[].weightBps`       | number | Yes      | Allocation weight in basis points          |

### Response

```json theme={null}
{
  "before": {
    "resolvedCount": 1,
    "yield": { "netApyPct": 5.2, "grossApyPct": 5.2, "weightedApyMean30dPct": 5.05 },
    "headline": "1 positions at 5.2% blended APY, behaving like ~1 independent bet.",
    "warnings": [],
    "caveats": []
  },
  "after": {
    "resolvedCount": 2,
    "yield": { "netApyPct": 5.04, "grossApyPct": 5.04, "weightedApyMean30dPct": 4.91 },
    "headline": "2 positions at 5.04% blended APY, behaving like ~1.74 independent bets.",
    "warnings": [],
    "caveats": []
  },
  "deltas": {
    "netApyPct": { "before": 5.2, "after": 5.04, "delta": -0.16 },
    "effectivePositions": { "before": 1, "after": 1.92, "delta": 0.92 },
    "oneFailureCostBps": { "before": 10000, "after": 6000, "delta": -4000 }
  },
  "factorDeltas": [
    {
      "dimension": "protocol",
      "key": "Morpho",
      "beforeBps": 0,
      "afterBps": 4000,
      "deltaBps": 4000
    }
  ],
  "headline": "Net APY -0.16pp, independent bets 1 to 1.74, CV +0.01."
}
```

The `before` and `after` objects use the same full response shape as [Analyze Portfolio](#analyze-portfolio). The example above is shortened for readability.

***

## Simulate History

<span style={{color: '#3B82F6', fontWeight: 'bold'}}>POST</span> `/portfolios/simulate`

Compound the realized blended APY history for a fixed-weight allocation book. This is descriptive and should not be treated as a forecast.

### Request

```bash theme={null}
curl -X POST "https://api.1tx.fi/api/v1/portfolios/simulate" \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "allocations": [
      {
        "instrumentId": "0x00002105c053a3e1290845e12a3eea14926472ce7f15da324cdf0700056fc04b",
        "weightBps": 6000
      },
      {
        "instrumentId": "0x00002105e1d832a44e229e784c3d4afba9a1ca44a288e34f7e5ddcba23155adc",
        "weightBps": 4000
      }
    ],
    "lookbackDays": 180,
    "principalUsd": 10000,
    "benchmark": "USD_INDEX"
  }'
```

### Request Body

| Field          | Type   | Required | Description                                                                                                                                  |
| -------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `allocations`  | array  | Yes      | Allocation book to simulate                                                                                                                  |
| `lookbackDays` | number | No       | History window in days, from `7` to `1095`. Defaults to backend configuration                                                                |
| `principalUsd` | number | No       | Starting principal in USD. Defaults to backend configuration                                                                                 |
| `benchmark`    | string | No       | Instrument ID to benchmark against, or `USD_INDEX` for a TVL-weighted stablecoin market benchmark. If omitted, a flat-rate benchmark is used |

### Response

```json theme={null}
{
  "resolvedCount": 2,
  "warnings": [],
  "lookbackDays": 180,
  "principalUsd": 10000,
  "finalValueUsd": 10248.31,
  "realizedReturnPct": 2.48,
  "annualizedPct": 5.08,
  "blendedApyVolPct": 0.38,
  "maxYieldDrawdownPct": 0.51,
  "benchmark": {
    "kind": "index",
    "label": "USD market avg (18 markets)",
    "finalValueUsd": 10212.44,
    "annualizedPct": 4.34,
    "outperformancePct": 0.74
  },
  "coveragePct": 100,
  "daysSimulated": 180,
  "headline": "2.48% over 180d (5.08% annualized), +0.74pp vs USD market avg (18 markets).",
  "caveats": [
    "Past correlation does not predict future correlation."
  ]
}
```

### Response Fields

| Field                         | Type      | Description                                                                   |
| ----------------------------- | --------- | ----------------------------------------------------------------------------- |
| `finalValueUsd`               | number    | Ending principal after compounding realized daily APY history                 |
| `realizedReturnPct`           | number    | Total simulated return over the simulated days                                |
| `annualizedPct`               | number    | Annualized rate implied by the simulation                                     |
| `blendedApyVolPct`            | number    | Standard deviation of the blended daily APY series                            |
| `maxYieldDrawdownPct`         | number    | Worst peak-to-trough APY drawdown in the blended series                       |
| `benchmark.kind`              | string    | `flatRate`, `instrument`, or `index`                                          |
| `benchmark.outperformancePct` | number    | Portfolio annualized APY minus benchmark annualized APY, in percentage points |
| `coveragePct`                 | number    | Percent of blended-history days with enough data coverage                     |
| `daysSimulated`               | number    | Number of days with usable blended history                                    |
| `headline`                    | string    | One-line summary of the simulation                                            |
| `caveats`                     | string\[] | Risk and methodology caveats that should be shown to users                    |

***

## TypeScript Example

```typescript theme={null}
const BASE_URL = 'https://api.1tx.fi/api/v1';
const API_KEY = process.env['1TX_API_KEY'];

async function analyzePortfolio(allocations: Array<{ instrumentId: string; weightBps: number }>) {
  const response = await fetch(`${BASE_URL}/portfolios/analyze`, {
    method: 'POST',
    headers: {
      'x-api-key': API_KEY ?? '',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ allocations }),
  });

  if (!response.ok) {
    throw new Error(`Failed to analyze portfolio: ${response.status}`);
  }

  return response.json();
}

const analysis = await analyzePortfolio([
  {
    instrumentId: '0x00002105c053a3e1290845e12a3eea14926472ce7f15da324cdf0700056fc04b',
    weightBps: 10000,
  },
]);

console.log(analysis.headline);
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Instruments API" icon="fingerprint" href="/api-reference/endpoints/instruments">
    Discover instruments and use enriched stability filters
  </Card>

  <Card title="Yield Index API" icon="chart-line" href="/api-reference/endpoints/yield-index">
    Query benchmark yield series and correlations
  </Card>
</CardGroup>
