> ## 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.

# Preview a loan

> Quote the agreement before recording it: the same body an issuance takes, priced identically, with nothing recorded.

A preview reads the body an issuance takes, runs every check issuance runs, prices the plan the same way, and records nothing. `reference` is ignored here and required on [the issuance](/api-reference/loans/issue); every other field behaves identically, so a preview that answered `200` is a body issuance will accept.

[Loans](/lending/loans) carries what is checked and what the answer freezes; [Pricing](/lending/pricing) carries the arithmetic. The wire form of every value is on [Model](/getting-started/model).

## Path parameters

<ParamField path="tenant_id" type="string" required>
  The Tenancy previewing. A key for another Tenancy answers `403`.
</ParamField>

## Body

The issuance body, `reference` ignored. The fields are documented once, on [Issue a loan](/api-reference/loans/issue); the checks run in the same order, the Client first — an unregistered `client_id` refuses a preview exactly as it refuses an issuance.

## Response

`200` with the quote: the same document an issuance answers, without `id`, `state` or `events` — nothing exists to carry them.

<ResponseField name="configuration" type="object" required>
  The Configuration the quote priced under, pinned as `{id, version}`.
</ResponseField>

<ResponseField name="terms" type="object" required>
  The stated terms, echoed.
</ResponseField>

<ResponseField name="periods" type="array" required>
  The plan: every Period's `scheduled_on`, `due_on`, `principal`, `interest`, `fee`, `tax` and the derived `payment`.
</ResponseField>

<ResponseField name="disclosure" type="object" required>
  The jurisdiction and the disclosed cost figure — the CAT, in `MX` — and the convention that produced it.

  | Field | Meaning |
  | - | - |
  | `convention` | The rule the figure was computed under, `mx-cat` in `MX`. |
  | `convention_version` | The version of that rule. |
  | `provisional` | `true` while the Platform has not confirmed that version against the authority's resolution. |

  The CAT in `MX` is provisional today, so a preview reads `provisional: true`. Printing a figure under a provisional rule is your decision; [what that means](/lending/mexico#the-cat).
</ResponseField>

<ResponseField name="regime" type="object" required>
  The jurisdiction's law as values: penalty rate, late fee, tolerance, penalty base, capitalisation, the acceleration conditions.

  What the preview shows here is what issuance freezes, field for field — the tolerance band as `tolerance` and each penalty ceiling as `penalty_ceiling_days` and `penalty_ceiling_bps`, each served only where the product states one. [The read](/api-reference/loans/read) says what each absence means.
</ResponseField>

<Info>
  A preview binds nothing. No figure served by one constrains a later issuance, and pricing runs once more at issuance on the same inputs — the two answers are identical.
</Info>

## Refusals

Everything [issuance refuses](/api-reference/loans/issue), with one difference: no `reference` means no `reference_reused` and no retry semantics — previewing twice writes nothing twice.

<RequestExample>
  ```bash Preview theme={null}
  BODY='{
    "client_id": "c-0001",
    "configuration_id": "inst-000001",
    "configuration_version": 1,
    "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"] }
  }'

  curl -X POST "https://api.capcells.com/v1/tenants/$TENANT_ID/loans/preview" \
    -H "Authorization: $(capcells_sign "$CAPCELLS_API_KEY" POST "/v1/tenants/$TENANT_ID/loans/preview" "$BODY")" \
    -H "Content-Type: application/json" \
    -d "$BODY"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "configuration": { "id": "inst-000001", "version": 1 },
    "terms": {
      "client_id": "c-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" }
      },
      …
      {
        "index": 12,
        "scheduled_on": "2027-03-02",
        "due_on": "2027-03-02",
        "principal": { "minor_units": 84204, "currency": "MXN" },
        "interest": { "minor_units": 2980, "currency": "MXN" },
        "fee": { "minor_units": 2084, "currency": "MXN" },
        "tax": { "minor_units": 810, "currency": "MXN" },
        "payment": { "minor_units": 90078, "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 422 Unregistered client theme={null}
  {
    "error": "loan: client is not registered: client c-0099",
    "code": "unknown_client"
  }
  ```
</ResponseExample>


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