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

# Create a loan

> Submit, approve, and disburse a loan in a single call. Returns an Active loan.

Creates a loan against an existing customer using one of the configured
loan products. The returned loan is already `Active` and ready for
repayments.

Loan terms (term length, repayment schedule, interest rate,
amortization, etc.) are inherited from the chosen `productId`, so the
request body carries only the three fields that vary per loan.

## Request body

<ParamField body="customerId" type="string" required>
  The **externalId** of the customer this loan is for — the identifier
  you chose when [creating the customer](/customers/create), not the
  numeric LMS id. The service resolves it against the LMS before
  submitting anything; an unknown externalId fails with `not_found`
  and no loan is created.
</ParamField>

<ParamField body="productId" type="integer" required>
  The loan product to use. List available products via
  [GET /v1/loan-products](/loan-products/list).
</ParamField>

<ParamField body="principal" type="number" required>
  Requested principal amount. Must be greater than 0 and within the
  product's `minPrincipal`/`maxPrincipal` bounds. The full principal is
  approved and disbursed in the same call.
</ParamField>

<ParamField body="externalId" type="string">
  Optional partner-supplied identifier for the loan (e.g. your wallet
  transaction reference). The LMS enforces uniqueness — a duplicate
  externalId is rejected with `aborted`. Once set, you can reference
  the loan on every repayment route via
  `/v1/loans/external/{externalId}/...` instead of the numeric LMS id.
</ParamField>

## Example

```bash theme={null}
curl -sf -X POST "$BASE/v1/loans" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "ext-ada-001",
    "productId": 1,
    "principal": 10000,
    "externalId": "loan-ext-12345"
  }'
```

## Response

`200 OK` returns the freshly-created and disbursed [loan object](/loans/overview).

```json theme={null}
{
  "id": "501",
  "accountNo": "000000501",
  "externalId": "loan-ext-12345",
  "customerId": "42",
  "customerName": "ext-ada-001 Customer",
  "loanProductId": "1",
  "loanProductName": "7-Day Loan",
  "status": "Active",
  "principal": 10000,
  "approvedPrincipal": 10000,
  "currencyCode": "TZS",
  "termFrequency": 7,
  "numberOfRepayments": 1,
  "interestRatePerPeriod": 11,

  "principalDisbursed": 10000,
  "principalPaid": 0,
  "principalOutstanding": 10000,
  "interestCharged": 77,
  "interestPaid": 0,
  "interestOutstanding": 77,
  "feeCharged": 0,
  "feePaid": 0,
  "feeOutstanding": 0,
  "penaltyCharged": 0,
  "penaltyPaid": 0,
  "penaltyOutstanding": 0,
  "totalRepayment": 0,
  "totalOutstanding": 10077,
  "totalOverpaid": 0,

  "nextDueDate": "2026-06-04",
  "nextDueAmount": 10077,
  "overdue": false,

  "repaymentSchedule": [
    {
      "period": 1,
      "fromDate": "2026-05-28",
      "dueDate": "2026-06-04",
      "complete": false,
      "principalDue": 10000,
      "principalOutstanding": 10000,
      "interestDue": 77,
      "interestOutstanding": 77,
      "totalDue": 10077,
      "totalOutstanding": 10077
    }
  ]
}
```

The `id` (string) is what every downstream call uses
([repayments](/repayments/repay), [get](/loans/get), etc.).
`totalOutstanding` is the headline "how much is owed" amount;
`nextDueDate` / `nextDueAmount` are the next instalment to collect.

<Note>
  Asymmetry to be aware of: the **request** `customerId` carries the
  customer's externalId, but the **response** `customerId` is the
  numeric LMS id (as a string) — the same value every read endpoint
  returns. Your externalId still appears on the customer object itself.
</Note>

## Errors

| Code                           | When                                                                                                    |
| ------------------------------ | ------------------------------------------------------------------------------------------------------- |
| `invalid_argument`             | Missing `customerId` / `productId` / `principal`, or `principal <= 0`                                   |
| `not_found`                    | `productId` does not exist, or no customer carries the supplied `customerId` externalId                 |
| `aborted` / `invalid_argument` | `principal` outside the product's allowed range, or the customer is in a state that disallows new loans |
| `aborted`                      | A loan with the supplied `externalId` already exists                                                    |
