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

# GET /api/indexer-race — First-Impairment Invisible Proof

> Returns captured proof that a vault's first impairment is invisible to metadata diffing, including the raw transaction nodes and both NAV readings.

Use this endpoint to retrieve the captured evidence that Orma's core thesis rests on: when a previously-healthy vault is impaired for the first time, the transaction's `PreviousFields` for the `Vault` node is entirely empty. Any indexer or oracle that detects losses by diffing metadata will see no change on that vault, while `AssetsTotal / sharesOutstanding` continues to report par. The correct NAV diverges by 19.61% and the metadata diff is `{}`.

## Parameters

This endpoint takes no parameters. The response is served from `demo/indexer-race.json` if present, falling back to `fixtures/indexer-race.json`.

## Request

```bash theme={null}
curl -s http://localhost:8787/api/indexer-race
```

## Response

```json theme={null}
{
  "serverTime": "2026-09-12T22:20:22Z",
  "ledgerIndex": 5263343,
  "capturedAt": "2026-09-12T21:07:56Z",
  "capturedDuring": "XRPL Lending Protocol Hackathon, Paris, 12-13 September 2026",
  "network": "devnet",
  "label": "Meridian Trade Finance I",
  "buildVersion": "3.4.0-rc5",
  "transactionHash": "075FE6D2E0F29919AF477A2A8F581A680805A006138BB967D8434611E49229C3",
  "transactionResult": "tesSUCCESS",
  "finding": "The first impairment of a previously-healthy vault is invisible to metadata diffing.",
  "why": "LossUnrealized was 0 (the type default) so rippled omits it from PreviousFields. Under cash-basis accounting impairment changes nothing else on the Vault, so PreviousFields is entirely {} while FinalFields carries a non-zero LossUnrealized.",
  "vaultId": "864C5A2DDCED78C6198B0703169D533B747A56E5F9398D832033F79E37E8C835",
  "loanBrokerId": "41BD2EA81CD03ED9EAC612BFFC6179AC742120FC4A5E0DD1D3E4DCE7DB5B2F38",
  "loanId": "60C170A9F1096E7200196E2DBC5849A5D8991C2F630123E77FF359B68F2B4188",
  "vaultNode": {
    "previousFields": {},
    "finalFields": {
      "AssetsTotal": "51000000",
      "AssetsAvailable": "41000000",
      "LossUnrealized": "10000000"
    },
    "healthyBefore": {
      "AssetsTotal": "51000000",
      "AssetsAvailable": "41000000",
      "LossUnrealized": "0"
    },
    "sharesOutstanding": "51000000"
  },
  "loanNode": {
    "previousFields": { "Flags": 0 },
    "finalFieldsFlags": 131072
  },
  "readings": {
    "naive":   { "formula": "AssetsTotal / sharesOutstanding", "value": "1.000000" },
    "correct": { "formula": "(AssetsTotal - LossUnrealized) / sharesOutstanding", "value": "0.803922" },
    "divergenceBps": 1961
  },
  "verdict": "PreviousFields is empty. An indexer diffing metadata sees no change on this vault."
}
```

## Response Fields

<ResponseField name="capturedAt" type="string">
  ISO 8601 timestamp of the transaction that produced this capture.
</ResponseField>

<ResponseField name="finding" type="string">
  One-sentence statement of the finding.
</ResponseField>

<ResponseField name="why" type="string">
  Explanation of the XRPL ledger behaviour that causes the finding.
</ResponseField>

<ResponseField name="vaultNode" type="object">
  The `AffectedNodes` entry for the `Vault` object from the transaction metadata.

  <Expandable title="vaultNode fields">
    <ResponseField name="previousFields" type="object">
      The fields that changed, as rippled records them. Empty (`{}`) on the first impairment of a healthy vault, because `LossUnrealized` was zero — its type default — and rippled omits fields equal to the type default from `PreviousFields`.
    </ResponseField>

    <ResponseField name="finalFields" type="object">
      The vault's field values after the transaction. `LossUnrealized` is present here with its new non-zero value.
    </ResponseField>

    <ResponseField name="healthyBefore" type="object">
      Orma's reconstruction of the vault's state before the impairment, filling in `LossUnrealized: "0"` where rippled omitted it.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="loanNode" type="object">
  The `AffectedNodes` entry for the `Loan` object. The flags field (`previousFields.Flags: 0` → `finalFieldsFlags: 131072`) is the only signal in the transaction metadata that something changed — and it is on a different object than the vault.
</ResponseField>

<ResponseField name="readings" type="object">
  Both NAV computations at the moment of impairment.

  <Expandable title="readings fields">
    <ResponseField name="naive" type="object">
      The NAV formula and result for `AssetsTotal / sharesOutstanding`.
    </ResponseField>

    <ResponseField name="correct" type="object">
      The NAV formula and result for `(AssetsTotal - LossUnrealized) / sharesOutstanding`.
    </ResponseField>

    <ResponseField name="divergenceBps" type="number">
      Basis-point gap between naive and correct readings at this moment.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="verdict" type="string">
  Plain-English conclusion: `"PreviousFields is empty. An indexer diffing metadata sees no change on this vault."`
</ResponseField>

<Note>
  Orma re-reads full ledger state every 4 seconds and never diffs `PreviousFields` — this capture explains why. Test loan flags by bit mask, not by equality: use `Flags & 0x20000` rather than `Flags === 131072`. A loan can carry more than one flag, and an equality test will stop matching the day it does.
</Note>
