> For the complete documentation index, see [llms.txt](https://docs.paragon.trade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.paragon.trade/developers/index-composition-api.md).

# Index Composition API

Authenticated REST API for retrieving index composition snapshots. Each snapshot describes the constituent assets and supply inputs effective at a given rebalance boundary.

> **Quick start:** `GET /v1/feeds/TOTAL2/composition` with your API key returns the current TOTAL2 constituent list.

## Scope

This API serves composition data only. It does not provide live prices, index levels, or weight calculations. All endpoints are read-only.

## Authentication

All endpoints require an API key passed via header.

```
Authorization: Bearer <api_key>
```

Rate limits are enforced per key. Exceeding your limit returns `429 Too Many Requests` with a `Retry-After` header.

To request an API key, contact the Paragon team.

## Feed Identifiers

Paragon index feeds use dedicated identifiers in this API. These differ from the Hyperliquid trading API identifiers.

| Index                      | Display Name | Composition API | Hyperliquid API | Feed Type |
| -------------------------- | ------------ | --------------- | --------------- | --------- |
| Bitcoin Dominance          | BTC.D        | `BTCD`          | `para:BTCD`     | `dom`     |
| Total Market Cap ex-BTC    | TOTAL2       | `TOTAL2`        | `para:TOTAL2`   | `mcap`    |
| Total Market Cap ex-Top 10 | OTHERS       | `OTHERS`        | `para:OTHERS`   | `mcap`    |

> **Note:** The Composition API omits the dot separator for BTC Dominance (`BTCD`). This maps to the canonical `BTC.D` feed.

## Endpoints

### Current Composition

Returns the latest published composition snapshot.

```
GET /v1/feeds/{feed_id}/composition
```

### Point-in-Time Composition

Returns the composition effective at a specific timestamp.

```
GET /v1/feeds/{feed_id}/composition?effective_timestamp={unix_ms}
```

### Composition History

Returns a paginated list of historical snapshots, most recent first.

```
GET /v1/feeds/{feed_id}/composition/history?limit={n}
```

### Parameters

| Parameter             | Type              | Location | Required | Description                                                          |
| --------------------- | ----------------- | -------- | -------- | -------------------------------------------------------------------- |
| `feed_id`             | string            | Path     | Yes      | Feed identifier (`BTCD`, `TOTAL2`, or `OTHERS`)                      |
| `effective_timestamp` | integer (Unix ms) | Query    | No       | Returns the composition valid at this time                           |
| `limit`               | integer           | Query    | No       | Number of historical snapshots to return (default: `10`, max: `100`) |

## Response Schema

### Common Fields

| Field            | Type                | Description                                                                                                    |
| ---------------- | ------------------- | -------------------------------------------------------------------------------------------------------------- |
| `feed_id`        | `string`            | Feed identifier (e.g., `TOTAL2`, `BTCD`)                                                                       |
| `feed_type`      | `string`            | `mcap` or `dom` - determines the shape of `constituents`                                                       |
| `divisor`        | `number`            | Scaling constant used in index computation.                                                                    |
| `timestamp`      | `string` (ISO 8601) | Time the API request was processed. **Not** the rebalance time.                                                |
| `last_rebalance` | `string` (ISO 8601) | Timestamp of the most recent rebalance                                                                         |
| `next_rebalance` | `string` (ISO 8601) | Next scheduled rebalance boundary (informational)                                                              |
| `constituents`   | `array` or `object` | **mcap feeds:** array of constituent objects. **dom feeds:** object with `numerator` and `denominator` arrays. |

### Constituent Fields

| Field                | Type      | Description                                                                        |
| -------------------- | --------- | ---------------------------------------------------------------------------------- |
| `symbol`             | `string`  | Canonical asset identifier (e.g., `ETH`, `BTC`)                                    |
| `rank`               | `integer` | Ordinal position determined at rebalance                                           |
| `circulating_supply` | `string`  | Circulating supply frozen at rebalance time. String-encoded to preserve precision. |

## Response Examples

### Market Cap Feed (TOTAL2)

For `mcap` feeds, `constituents` is a flat array:

```json
{
  "feed_id": "TOTAL2",
  "feed_type": "mcap",
  "divisor": 1000000,
  "timestamp": "2026-02-12T09:32:14Z",
  "last_rebalance": "2026-02-12T00:00:00Z",
  "next_rebalance": "2026-02-13T00:00:00Z",
  "constituents": [
    { "symbol": "ETH", "rank": 1, "circulating_supply": "120523871.44" },
    { "symbol": "XRP", "rank": 2, "circulating_supply": "57124830921" },
    { "symbol": "BNB", "rank": 3, "circulating_supply": "145887575.82" }
  ]
}
```

### Dominance Feed (BTC.D)

For `dom` feeds, `constituents` is an object with `numerator` and `denominator` arrays:

```json
{
  "feed_id": "BTCD",
  "feed_type": "dom",
  "divisor": 1,
  "timestamp": "2026-02-12T09:32:14Z",
  "last_rebalance": "2026-02-12T00:00:00Z",
  "next_rebalance": "2026-02-13T00:00:00Z",
  "constituents": {
    "numerator": [
      { "symbol": "BTC", "rank": 1, "circulating_supply": "19842356" }
    ],
    "denominator": [
      { "symbol": "BTC", "rank": 1, "circulating_supply": "19842356" },
      { "symbol": "ETH", "rank": 2, "circulating_supply": "120523871.44" },
      { "symbol": "XRP", "rank": 3, "circulating_supply": "57124830921" }
    ]
  }
}
```

## Code Examples

### Fetch TOTAL2 Composition

```python
import requests

API_KEY = "your_api_key"
BASE_URL = "https://api.paragon.trade/v1"

headers = {"Authorization": f"Bearer {API_KEY}"}

response = requests.get(f"{BASE_URL}/feeds/TOTAL2/composition", headers=headers)
response.raise_for_status()

data = response.json()
print(f"Feed: {data['feed_id']} | Last rebalance: {data['last_rebalance']}")

for c in data["constituents"]:
    print(f"  #{c['rank']} {c['symbol']}: supply={c['circulating_supply']}")
```

### Fetch BTC.D Composition (Dominance Feed)

```python
response = requests.get(f"{BASE_URL}/feeds/BTCD/composition", headers=headers)
response.raise_for_status()

data = response.json()
numerator = data["constituents"]["numerator"]
denominator = data["constituents"]["denominator"]

print(f"Numerator assets: {len(numerator)}")
print(f"Denominator assets: {len(denominator)}")
```

### Historical Lookup

```python
# Last 5 rebalance snapshots
response = requests.get(
    f"{BASE_URL}/feeds/TOTAL2/composition/history",
    headers=headers,
    params={"limit": 5},
)
response.raise_for_status()

for snapshot in response.json():
    print(f"{snapshot['last_rebalance']}: {len(snapshot['constituents'])} constituents")
```

## Data Guarantees

* **Immutability** - Once published, a composition snapshot never changes. Multiple requests for the same snapshot return identical data.
* **Supply freeze** - `circulating_supply` values are snapshotted at each daily rebalance and remain fixed until the next rebalance.
* **Divisor stability** - The `divisor` is constant between rebalances.
* **Deterministic ordering** - Constituents are sorted by `rank` ascending. Ordering is stable across requests.
* **Availability** - If a new composition is not yet available at the expected rebalance time, the API continues serving the most recent valid snapshot. The API never serves partial or incomplete compositions.

## Error Responses

| Status | Meaning                                                              |
| ------ | -------------------------------------------------------------------- |
| `200`  | Success                                                              |
| `400`  | Bad request - malformed query parameters                             |
| `401`  | Unauthorized - missing or invalid API key                            |
| `404`  | Unknown feed ID or no composition exists for the requested timestamp |
| `429`  | Rate limit exceeded - retry after `Retry-After` header duration      |
| `5xx`  | Internal Service Error - retry your request                          |

## Versioning

This API uses path-level versioning (`/v1/`). Non-breaking additions (new fields, new feeds) may be introduced within a version. Breaking schema changes require a new version path.

> [API Overview](/developers/api.md) | [External Pricing](/markets/crypto-indices/external-pricing.md) | [Contract Specifications](/markets/specifications.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.paragon.trade/developers/index-composition-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
