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

# Model

> How money, dates and identifiers are written, and which figures the Platform derives rather than stores.

The Platform's **model** is one set of conventions: how money, dates and identifiers are written, and which figures are derived rather than stored.

The Platform records what you report, prices the agreement once at issuance, and derives every later figure from the two. Nothing recorded is edited or deleted; a withdrawal is itself a fact, and the withdrawn one stays readable while contributing to nothing. No scheduled job posts a figure.

## Values

Four fields on a Loan, a Receipt or a Client carry an instant, and each ends in `_at`. Every other date-bearing field carries a civil date, whatever its name: `anchor`, `value_date`, `due_on` and the `on` an event body takes.

Five values carry a fixed form on the wire.

| Value    | On the wire                               | Rule                                                                                                      |
| -------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| Amount   | `{"minor_units":125000,"currency":"MXN"}` | An integer count of the currency's minor units: this one is MXN 1,250.00, and a decimal is refused.       |
| Currency | `"MXN"`, inside every Amount              | An ISO 4217 code, matched exactly, that fixes how many minor units make one unit.                         |
| Rate     | `"45.5"`                                  | A decimal percentage in a string; `rate` and `penalty_rate` are per year, and a JSON number is refused.   |
| Date     | `"2026-03-02"`                            | ISO `YYYY-MM-DD` carrying no time and no zone; a timestamp is refused rather than truncated.              |
| Refusal  | `{"error":"<prose>"}`                     | Prose with no code and no type on every refusal a route answers, so a client branches on the HTTP status. |

One issuance body carries every form, and a refused request answers the fifth.

<CodeGroup>
  ```json Issuance body theme={null}
  {
    "reference": "loan-2026-03-02-8841",
    "client_id": "client-8841",
    "configuration_id": "0f7c9a1e-3b6d-4a52-9f10-27c4d8e5b3a6",
    "configuration_version": 3,
    "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"] }
  }
  ```

  ```json Refusal theme={null}
  {
    "error": "loan: selected term is outside the configuration"
  }
  ```
</CodeGroup>

## Fields

A **Reference** is your own identifier for one issuance or one reported Receipt, and the first request carrying it answers `201`. Every path begins `/v1/tenants/{tenant_id}/`, and a key acts for that one Tenancy.

Each identifier is chosen by one side, has one shape, and behaves one way on a repeat.

| Field              | Chosen by    | Shape                                                                                                             | On a repeat                                                                          |
| ------------------ | ------------ | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `id`               | You          | A Client's identifier, 1 to 64 characters of letters, digits, hyphen and underscore, named `client_id` elsewhere. | The same `label` answers `200`; a different or omitted one is refused `409`.         |
| `reference`        | You          | The same grammar, unique within your Tenancy for each kind of record.                                             | The same statements answer `200`; the first that differs is named and refused `409`. |
| `loan_id`          | The Platform | A UUID, and the only address a Loan answers to.                                                                   | Not applicable.                                                                      |
| `configuration_id` | The Platform | A Product's UUID from `/product-configurations`, sent with `configuration_version`.                               | Not applicable.                                                                      |

A statement the retry omits is compared as `none`, so dropping a field the first request carried is refused rather than replayed.

## Derivation

A read that answers as of a date names it in the query parameter `on`. A request without it is refused, because the Platform chooses no date for a lending read. A date that has not arrived is answered.

Each figure is either computed at issuance and stored, or derived by the read that asks for it.

| Figure                                                           | Where it comes from                                        | What changes it                                                                                              |
| ---------------------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| The Schedule, and each Period's principal, interest, fee and tax | Computed at issuance and stored                            | Nothing rewrites the stored rows; a borrower's Election re-plans the Periods inside the as-of reads.         |
| A Loan's state                                                   | Folded from that Loan's recorded facts on every read       | Recording a fact about the Loan or withdrawing one, and reporting or reversing a Receipt that discharges it. |
| An Allocation                                                    | Recomputed from your reported Receipts in value-date order | Reporting a Receipt, or reversing one.                                                                       |
| Arrears                                                          | Derived for the date the request names                     | Any fact value-dated on or before that date, whenever it was reported.                                       |

## Invariants

Five properties hold across every figure the Platform reports.

* **Derived.** Every figure is derived from the facts on record.
* **Not accumulated.** No figure is stored as a running total.
* **Not edited.** A wrong fact is withdrawn rather than changed, and every figure is re-derived without it.
* **As-of.** The Platform derives a dated figure for the date your request names, and for no other.
* **Versioned.** A Product change never disturbs a Loan already issued.

## Restrictions

Seven refusals follow from the conventions above.

* No write except an issuance and a reported Receipt carries a Reference, so a retried cancellation, acceleration, write-off, retraction or reversal is refused `409`.
* No Reference guards Product creation, which writes a second Product on every request rather than replaying.
* No Reference is spent by a request the Platform refused.
* No figure the Platform cannot state arrives as `null`: the field is omitted, and `anomalies` names why.
* No amount is converted, because two currencies never meet in one operation.
* No Arrears are derived for a date before a Loan's anchor, and the `payment-options` read leaves such a Loan out.
* No route paginates or sorts, and no list narrows except Loans, by `client_id`.
