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

# Iris Core

> Query loans, positions, bond backing, venues, protocol configuration, and token metadata.

## How to query Iris Core data with the API?

You can query Iris Core data with the **GraphQL API**. Queries run against the [GraphQL Playground](https://api.iris.credit/graphql).

A few conventions carry through every example:

* Examples read from the Ethereum mainnet staging fork (**VNet**, `chainId: 9991`); an integration moves to another network by changing the `chainId`.
* By default the API returns only the first **50** results; pass `limit` (up to 1000) and page with cursors for more.
* Addresses are lowercase hex, and filters are exact-match.
* `BigInt` values are returned as strings; rates and LLTVs are WAD (`1e18`), amounts are in the token's own decimals.
* Plural query names are generated from table names: `blmParamss`, `marketDatas`, and `whitelistEntrys` are not typos.

## Discovery and Listing

### Loans List

A loan is identified by its **pod**, the isolated clone address holding that borrower's position. `(chainId, pod)` is the primary key everywhere in this API.

<Tabs>
  <Tab title="All Loans">
    ```graphql theme={null}
    query {
      loans(limit: 20, orderBy: "maturity", orderDirection: "desc") {
        totalCount
        items {
          chainId
          pod
          borrower
          solver
          fixedRate
          maturity
          collateralToken { symbol decimals }
          debtToken { symbol decimals }
        }
        pageInfo { hasNextPage endCursor }
      }
    }
    ```
  </Tab>

  <Tab title="By Borrower">
    ```graphql theme={null}
    query {
      loans(where: { borrower: "0xaacce4ec50328120ef3899a978e87fca6b8bbe84" }, limit: 20) {
        totalCount
        items {
          pod
          solver
          fixedRate
          maturity
          duration
          collateralToken { symbol }
          debtToken { symbol }
        }
      }
    }
    ```
  </Tab>

  <Tab title="By Solver">
    ```graphql theme={null}
    query {
      loans(where: { solver: "0xe05fcc23807536bee418f142d19fa0d21bb0cff7" }, limit: 20) {
        totalCount
        items {
          pod
          borrower
          fixedRate
          overdueRate
          bondLltv
          maturity
        }
      }
    }
    ```
  </Tab>

  <Tab title="Specific Loan">
    ```graphql theme={null}
    query {
      loan(chainId: 9991, pod: "0x57704b581a00f25c00fa9b44934763958387116d") {
        borrower
        solver
        venueBitmap
        maturity
        duration
        overduePeriod
        fixedRate
        overdueRate
        bondLltv
        fee
        collateralToken { address symbol decimals }
        debtToken { address symbol decimals }
      }
    }
    ```
  </Tab>
</Tabs>

Loan rows are immutable: they record the quote as accepted when the loan is opened. Everything that moves lives on `position`.

## Position Metrics

### Collateral, Debt & Bond

`position` is one-to-one with `loan` on `(chainId, pod)` and holds everything mutable.

<Tabs>
  <Tab title="All Positions">
    ```graphql theme={null}
    query {
      positions(limit: 20, orderBy: "debt", orderDirection: "desc") {
        totalCount
        items {
          pod
          collateral
          debt
          bond
          bondRequirement
          lastUpdate
          venueId
          loan {
            maturity
            overduePeriod
            collateralToken { symbol decimals priceUsd }
            debtToken { symbol decimals priceUsd }
          }
        }
      }
    }
    ```
  </Tab>

  <Tab title="Specific Position">
    ```graphql theme={null}
    query {
      position(chainId: 9991, pod: "0x57704b581a00f25c00fa9b44934763958387116d") {
        collateral
        debt
        bond
        bondRequirement
        collateralIndex
        debtIndex
        fixedLeg
        floatingLeg
        surplus
        lastUpdate
        venueId
        data
      }
    }
    ```
  </Tab>
</Tabs>

`bond` and `bondRequirement` are in the **debt** token's decimals, `collateral` in the collateral token's; a closed loan keeps its row with `debt: "0"`.

### Fixed vs Floating Legs

```graphql theme={null}
query {
  positions(limit: 20) {
    items {
      pod
      debt
      fixedLeg
      floatingLeg
      surplus
      lastUpdate
      loan { fixedRate overdueRate maturity debtToken { symbol decimals } }
    }
  }
}
```

| Field         | Meaning                                                              |
| ------------- | -------------------------------------------------------------------- |
| `fixedLeg`    | Fixed interest accrued and owed by the borrower, in debt-token units |
| `floatingLeg` | Venue interest accrued against the position over the same window     |
| `surplus`     | Collateral yield accrued to the solver                               |
| `lastUpdate`  | Timestamp of the last accrual, i.e. how stale the legs are           |

Legs are as of `lastUpdate`, not as of now.

### Bond Health

```graphql theme={null}
query {
  positions(where: { bondRequirement_gt: "0" }, limit: 50) {
    items {
      pod
      bond
      bondRequirement
      fixedLeg
      floatingLeg
      loan { solver bondLltv debtToken { symbol decimals } }
    }
  }
}
```

A bond is unhealthy when `bond < bondRequirement`, or when `ceil((floatingLeg - fixedLeg) × 1e18 / bond)` exceeds `bondLltv`. See [Bond Mechanics](/solver/economics/bond-mechanic).

## Loan Status

Status is not a column: it is derived at read time from `debt`, `maturity`, and `overduePeriod`.

```graphql theme={null}
query {
  loans(limit: 50) {
    items {
      pod
      maturity
      overduePeriod
      position { debt }
    }
  }
}
```

With `now` in unix seconds:

| Status         | Condition                                                   |
| -------------- | ----------------------------------------------------------- |
| `closed`       | `debt == 0`                                                 |
| `active`       | `debt > 0` and `now <= maturity`                            |
| `overdue`      | `debt > 0` and `maturity < now <= maturity + overduePeriod` |
| `liquidatable` | `debt > 0` and `now > maturity + overduePeriod`             |

Only `closed` is expressible as a filter. Fetch the live set with `positions(where: { debt_gt: "0" })` and classify client-side, comparing `now` against the indexed block timestamp from `_meta { status }`.

## Position Tracking

### Borrower All Loans Position

Everything a borrower needs on one screen: terms, live balances, and both USD legs.

```graphql theme={null}
query BorrowerPositions($borrower: String!) {
  loans(where: { borrower: $borrower }, orderBy: "maturity", orderDirection: "asc", limit: 100) {
    totalCount
    items {
      pod
      solver
      fixedRate
      overdueRate
      maturity
      overduePeriod
      collateralToken { symbol decimals priceUsd }
      debtToken { symbol decimals priceUsd }
      position {
        collateral
        debt
        fixedLeg
        lastUpdate
        venueId
        venueAdapter { adapter }
      }
    }
  }
}
```

```json theme={null}
{ "borrower": "0xaacce4ec50328120ef3899a978e87fca6b8bbe84" }
```

### Borrower Account Overview

Loans, claimable balances, and delegated managers in one request.

```graphql theme={null}
query BorrowerOverview($account: String!) {
  loans(where: { borrower: $account }, limit: 100) {
    totalCount
    items { pod maturity overduePeriod position { debt collateral } }
  }
  claimables(where: { account: $account }) {
    items { amount token { symbol decimals priceUsd } }
  }
  authorizations(where: { authorizer: $account, isAuthorized: true }) {
    items { authorized }
  }
}
```

### Solver Book

A solver's whole exposure: loans underwritten, bond posted against bond required, and unclaimed earnings.

```graphql theme={null}
query SolverBook($solver: String!) {
  loans(where: { solver: $solver }, orderBy: "maturity", orderDirection: "asc", limit: 100) {
    totalCount
    items {
      pod
      borrower
      fixedRate
      overdueRate
      bondLltv
      maturity
      overduePeriod
      debtToken { symbol decimals priceUsd }
      position {
        debt
        bond
        bondRequirement
        fixedLeg
        floatingLeg
        surplus
        lastUpdate
      }
    }
  }
  claimables(where: { account: $solver }) {
    items { amount token { symbol decimals priceUsd } }
  }
}
```

```json theme={null}
{ "solver": "0xe05fcc23807536bee418f142d19fa0d21bb0cff7" }
```

## Bond

### BLMs List

A bond liquidity manager (BLM) sets how much bond a solver must post.

```graphql theme={null}
query {
  blms {
    items {
      chainId
      address
      params { totalCount }
      whitelist { totalCount }
    }
  }
}
```

A BLM with whitelist rows is a `WhitelistBlm`; one with none is a plain `Blm`.

### Bond Curve Parameters

Curves are keyed per **debt** token, so a single BLM prices USDC and USDT loans independently.

<Tabs>
  <Tab title="All BLMs">
    ```graphql theme={null}
    query {
      blmParamss(limit: 50) {
        items {
          slope
          intercept
          blm { address }
          token { address symbol decimals }
        }
      }
    }
    ```
  </Tab>

  <Tab title="Specific BLM">
    ```graphql theme={null}
    query {
      blm(chainId: 9991, address: "0xe0ae439c391d8dcf870a3045f09fe901fe8ef07b") {
        address
        params {
          items {
            slope
            intercept
            token { symbol decimals }
          }
        }
      }
    }
    ```
  </Tab>
</Tabs>

`position.bondRequirement` is computed once at loan open as `debt × (slope × duration / 86400 + intercept) / 1e18`; see [Bond Mechanics](/solver/economics/bond-mechanic).

### Solver Whitelist

```graphql theme={null}
query {
  whitelistEntrys(where: { isWhitelisted: true }, limit: 100) {
    totalCount
    items {
      account
      isWhitelisted
      blm { address }
    }
  }
}
```

Rows persist with `isWhitelisted: false` after a removal, so always filter on the flag.

### Enabled Bond LLTVs

The set of bond LLTVs governance permits a quote to use.

```graphql theme={null}
query {
  bondLltvs {
    items { chainId lltv }
  }
}
```

## Venue & Settlement

### Venue Adapters

Every position sits in exactly one venue, addressed by `venueId` and served by an adapter contract.

```graphql theme={null}
query {
  venueAdapters {
    items {
      venueId
      adapter
      positions(limit: 5, orderBy: "lastUpdate", orderDirection: "desc") {
        totalCount
        items { pod debt lastUpdate }
      }
    }
  }
}
```

`loan.venueBitmap` is the set of venues the loan may move within (bit `n` set = venue `n` allowed); `position.venueId` is where it is right now.

### Enabled Market Data

```graphql theme={null}
query {
  marketDatas {
    items { chainId data }
  }
}
```

`data` is `keccak256` of a venue-market blob; hash the blob you hold to check whether it is enabled.

### Refinance & Rebase State

Refinancing moves a position between venues, re-snapshotting the venue indices and the market blob.

```graphql theme={null}
query {
  positions(orderBy: "lastUpdate", orderDirection: "desc", limit: 20) {
    items {
      pod
      venueId
      collateralIndex
      debtIndex
      data
      lastUpdate
      venueAdapter { adapter }
      loan { venueBitmap }
    }
  }
}
```

`position.data` is the raw blob for the current venue (`0x` when the venue takes no parameters), the pre-image whose hash appears in `marketDatas`.

## Protocol Configuration

### Owner, Fee & Fee Recipient

One singleton row per chain.

```graphql theme={null}
query {
  config(chainId: 9991) {
    owner
    feeRecipient
    fee
    venueAdapters { items { venueId adapter } }
    blms { items { address } }
    bondLltvs { items { lltv } }
    marketData { totalCount }
  }
}
```

`config.fee` is the live protocol fee; `loan.fee` is the value snapshotted when that loan was opened.

### Authorization

Borrowers can authorize a manager to act on their positions.

```graphql theme={null}
query {
  authorizations(where: { isAuthorized: true }, limit: 100) {
    items { authorizer authorized isAuthorized }
  }
}
```

Rows persist with `isAuthorized: false` after revocation, so filter on the flag.

### Claimable Balances

Credited earnings (solver interest, protocol fees, collateral surplus) that have not yet been claimed.

```graphql theme={null}
query {
  claimables(where: { account: "0xe05fcc23807536bee418f142d19fa0d21bb0cff7" }) {
    totalCount
    items {
      amount
      token { symbol decimals priceUsd }
    }
  }
}
```

One row per `(chainId, token, account)`; claims decrement rather than delete, so a zero `amount` means fully claimed.

## Token Metadata

Token metadata is resolved off-chain for every token the protocol references. USD prices are sourced from [DefiLlama](https://defillama.com).

### Token List

```graphql theme={null}
query {
  tokens(orderBy: "symbol", orderDirection: "asc", limit: 100) {
    totalCount
    items {
      chainId
      address
      name
      symbol
      decimals
      logoURI
      priceUsd
    }
  }
}
```

Tokens that don't answer a metadata call are stored with `UNKNOWN` placeholders rather than omitted.

### Prices

```graphql theme={null}
query {
  tokens(orderBy: "priceUsd", orderDirection: "desc", limit: 10) {
    items { symbol decimals priceUsd }
  }
}
```

`priceUsd` is refreshed every 5 minutes, is **nullable**, and is a `Float`; parse it as a number, not a `BigInt`.

### Token Relations

Any token address field expands in place, which removes the second round trip.

```graphql theme={null}
query {
  loans(limit: 5) {
    items {
      pod
      collateralToken { symbol decimals priceUsd logoURI }
      debtToken { symbol decimals priceUsd logoURI }
      position { collateral debt }
    }
  }
}
```

The relation replaces the raw string, so request `{ address }` if you need the hex.

## Historical Data

The API serves **current state only**: every row reflects the latest indexed block, with no event log, snapshot table, or timeseries. For now, read the contract event logs directly, or index them yourself; historical timeseries data will be added to the API in a future release.

## Paging, Ordering & Filtering

Every plural query accepts the same arguments: `where`, `orderBy`, `orderDirection`, `limit`, and cursor paging via `after` / `before` with `pageInfo`.

```graphql theme={null}
query {
  loans(
    where: {
      debtToken: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
      fixedRate_gte: "70000000000000000"
    }
    orderBy: "fixedRate"
    orderDirection: "desc"
    limit: 25
  ) {
    totalCount
    items { pod fixedRate maturity debtToken { symbol } }
    pageInfo { hasNextPage hasPreviousPage startCursor endCursor }
  }
}
```

Each column exposes suffixed operators, combined with AND by default:

| Suffix                               | Applies to | Example                       |
| ------------------------------------ | ---------- | ----------------------------- |
| *(none)*, `_not`                     | all        | `borrower: "0x…"`             |
| `_in`, `_not_in`                     | all        | `chainId_in: [1, 9991]`       |
| `_gt`, `_gte`, `_lt`, `_lte`         | numeric    | `maturity_gt: "1785220778"`   |
| `_contains`, `_not_contains`         | strings    | `pod_contains: "abc"`         |
| `_starts_with`, `_ends_with`         | strings    | `solver_starts_with: "0xe05"` |
| `_not_starts_with`, `_not_ends_with` | strings    | `pod_not_starts_with: "0x00"` |

`AND` and `OR` take lists of filters and nest:

```graphql theme={null}
query {
  loans(
    where: {
      OR: [
        { AND: [{ debtToken: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" }, { fixedRate_gt: "80000000000000000" }] }
        { solver: "0xe05fcc23807536bee418f142d19fa0d21bb0cff7" }
      ]
    }
    limit: 25
  ) {
    totalCount
    items { pod solver fixedRate debtToken { symbol } }
  }
}
```

Three notes: `limit` above the 1000 cap fails with a masked `INTERNAL_SERVER_ERROR` ("Unexpected error."); `where` cannot traverse relations, so cross-entity conditions are a second query plus a client-side join; prefer cursors over `offset` for full scans, since `offset` can skip or repeat rows if a write lands mid-scan.
