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

# Read a loan

> The whole record: the folded state, every recorded fact, the frozen plan and the regime it was priced under.

One route answers the whole Loan. Nothing on it is stored as a status: `state` is folded from the recorded facts on every read, so the answer and the facts it derives from can never disagree. [Loans](/lending/loans) carries the states, the precedence and the freeze.

## Path parameters

<ParamField path="tenant_id" type="string" required>
  The Tenancy the Loan belongs to.
</ParamField>

<ParamField path="loan_id" type="string" required>
  The Loan's identifier, as the issuance answered it. Another Tenancy's Loan and one that never existed are both `404`.
</ParamField>

## Response

<ResponseField name="state" type="string" required>
  Folded on every read: `active`, `closed`, `cancelled`, `written_off`, `ceded`, `held`, `voided`, `rescinded`, `withdrawn` or `restructured`. Precedence where facts pile up: voided over held over cancelled over rescinded and withdrawn over ceded over written\_off over closed over restructured over active. This read takes no date, so a hold nobody confirmed reads `held` even past its last day; [the listing](/api-reference/loans/list) answers `expired` with `on`.
</ResponseField>

<ResponseField name="events" type="array" required>
  Every recorded fact, retracted ones included.

  <Expandable title="event">
    <ResponseField name="id" type="string" required>
      The identifier [a retraction names](/api-reference/loans/retraction). The derived `settled` event carries none — no row holds it.
    </ResponseField>

    <ResponseField name="kind" type="string" required>
      `issued`, `cancelled`, `accelerated`, `written_off`, `rolled_over`, `returned`, `ceded`, `suspended`, `suspension_ended`, `confirmed`, `voided`, `rescinded`, `withdrawn`, `waived`, `restructured`, `settled_for_less` — or `settled`, which is derived and written by nothing.
    </ResponseField>

    <ResponseField name="occurred_on" type="string" required>
      The civil day the fact is about — yours, never a clock's.
    </ResponseField>

    <ResponseField name="recorded_at" type="string" required>
      RFC 3339: when the row was written. A different fact from `occurred_on`, and the distinction is load-bearing.
    </ResponseField>

    <ResponseField name="act" type="object">
      The account the act gave of itself: `reference`, `actor`, `basis`, and your `context` where one was stated. A fact recorded before acts existed carries no `act` key at all.
    </ResponseField>

    <ResponseField name="to" type="string">
      On a `suspended` event, the last day of the window; its first is `occurred_on`. Beside it, `ended_on` where [an early end](/api-reference/loans/suspension-end) in force restarted the clock. On a `suspension_ended` event, `suspension_id` names the suspension it ended.
    </ResponseField>

    <ResponseField name="retraction" type="object">
      Present on a withdrawn fact: `on`, `recorded_at`, and the withdrawing act's own account. A withdrawn fact contributes to nothing and stays readable.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="anomalies" type="array" required>
  Contradictions the fold resolved rather than refused — empty on a healthy Loan. Each names its kind and the pair of facts behind it.
</ResponseField>

<ResponseField name="rolled_over" type="integer" required>
  How many rollovers stand in force. Served on every Loan, zero included.
</ResponseField>

<ResponseField name="returns" type="array">
  What each [return](/api-reference/loans/return) in force produced, oldest first: `act`, `on`, `amount`, `unwound_principal`, `principal_owed_back`, `interest_owed_back`, `still_owed` by charge, `beyond_the_loan` — your own refund, outside the book — and `returned_whole`. Derived on every read; absent on a Loan nothing went back on.
</ResponseField>

<ResponseField name="paid" type="object">
  What the Receipts have settled against this Loan to date — the same figure as the [listing row](/api-reference/loans/list). A stated zero where nothing reached the Loan; absent where the Client's allocation cannot be derived, with the reason in `anomalies`.
</ResponseField>

<ResponseField name="owes" type="boolean" required>
  Whether the Loan still owes anything, by the rule the listing states it: an active or written-off Loan owes the Tenancy, a ceded one owes the assignee, a closed or cancelled one owes nothing.
</ResponseField>

<ResponseField name="owed_to" type="string">
  `tenant` or `assignee`; absent where the Loan owes nothing.
</ResponseField>

<ResponseField name="closed_on" type="string">
  The value date of the discharging Receipt. Present exactly on a `closed` Loan — a written-off Loan never carries one, even after full recovery.
</ResponseField>

<ResponseField name="write_off" type="object">
  Present where a write-off stands: `on`, `cost` — the debt at the judgement, taken apart by charge — and `recovered`. [Delinquency](/lending/delinquency) carries the worked block.
</ResponseField>

<ResponseField name="configuration" type="object" required>
  `{id, version}`, pinned at issuance.
</ResponseField>

<ResponseField name="terms" type="object" required>
  The stated terms echoed: `client_id`, `reference`, `principal`, `term_periods`, `rate`, `penalty_rate`, `anchor`, `jurisdiction`, `tax`, and `down_payment`, `schedule`, `merchant_ref` and `context` where stated.
</ResponseField>

<ResponseField name="periods" type="array" required>
  The plan as issued — frozen. Where the Loan stands now is [the serviced Schedule](/api-reference/loans/schedule).
</ResponseField>

<ResponseField name="disclosure" type="object" required>
  The jurisdiction and the disclosed cost figure, computed once at issuance and never restated, with the convention it was computed under: `convention`, `convention_version` and `provisional`.

  The three are frozen with the figure. A Loan issued while the rule was provisional reads `provisional: true` for its whole life, whatever is confirmed afterwards; a Loan issued under a confirmed version reads `false`. A Loan issued before the Platform named its conventions reads `mx-cat`, version `1`, provisional, which is what was true of every one of them. [What provisional means](/lending/mexico#the-cat).
</ResponseField>

<ResponseField name="regime" type="object" required>
  The jurisdiction's law as values, frozen: `penalty_rate`, `late_fee`, `tolerance_days`, `penalty_base`, `capitalises`, `acceleration`.

  Three fields are served only where the Loan carries them.

  | Field | Present when |
  | - | - |
  | `tolerance` | The contract states a tolerance band. Absent means no band — and a band of nothing is no band. |
  | `penalty_ceiling_days` | A per-period ceiling is in force. Absent means the penalty accrues for as long as the period stands overdue. |
  | `penalty_ceiling_bps` | A whole-loan ceiling is in force. Absent means the penalty is not bounded across the Loan. |

  The example below is a Loan that carries none of the three, so none of the keys appears.
</ResponseField>

<RequestExample>
  ```bash Read theme={null}
  curl "https://api.capcells.com/v1/tenants/$TENANT_ID/loans/$LOAN_ID" \
    -H "Authorization: $(capcells_sign "$CAPCELLS_API_KEY" GET "/v1/tenants/$TENANT_ID/loans/$LOAN_ID")"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "id": "7771aef0-9e65-4a0a-a902-aab4e970d33f",
    "tenant_id": "t-0001",
    "state": "active",
    "created_at": "2026-08-18T22:26:41.420114Z",
    "rolled_over": 0,
    "events": [
      { "id": "…0001", "kind": "issued", "occurred_on": "2026-03-02", "recorded_at": "2026-08-18T22:26:41.420114Z" }
    ],
    "anomalies": [],
    "configuration": { "id": "inst-000001", "version": 1 },
    "terms": {
      "client_id": "c-0001",
      "reference": "loan-0001",
      "principal": { "minor_units": 800000, "currency": "MXN" },
      "term_periods": 12,
      "rate": "45.5",
      "penalty_rate": "60",
      "anchor": "2026-03-02",
      "jurisdiction": "MX",
      "tax": { "rate": "16", "on": ["interest", "fee", "penalty", "late_fee"] }
    },
    "periods": [
      {
        "index": 1,
        "scheduled_on": "2026-04-02",
        "due_on": "2026-04-06",
        "principal": { "minor_units": 51291, "currency": "MXN" },
        "interest": { "minor_units": 31344, "currency": "MXN" },
        "fee": { "minor_units": 2083, "currency": "MXN" },
        "tax": { "minor_units": 5348, "currency": "MXN" },
        "payment": { "minor_units": 90066, "currency": "MXN" }
      },
      …
    ],
    "disclosure": { "jurisdiction": "MX", "figure": "64.9", "convention": "mx-cat", "convention_version": 1, "provisional": true },
    "regime": {
      "penalty_rate": "60",
      "late_fee": { "minor_units": 15000, "currency": "MXN" },
      "tolerance_days": 0,
      "penalty_base": "overdue_principal",
      "capitalises": false,
      "acceleration": { "forbidden": false, "missed_periods": 3, "notice_days": 15 }
    }
  }
  ```

  ```json 404 theme={null}
  {
    "error": "loan: loan not found",
    "code": "not_found"
  }
  ```
</ResponseExample>


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