Added Installment Plans to Lithic Ledger
October 27, 2026
Lithic Credit Ledger
Programs can convert and track balances using Installment Plans
Customers using Lithic Credit Ledger
None
Overview
Credit accounts can now carry installment plans. An installment plan takes a balance left unpaid and spreads it over a fixed number of installments. Each installment is billed in a future cycle and is due by that cycle's payment due date. An account can have several plans open at the same time.
For a program configured for installments, there are two new endpoints:
- The plan as it stands now. These endpoints return the live plan, which changes as installments are billed and paid.
- The plan as it stood on each statement. When a statement is generated, Lithic records a snapshot of every plan that was open during that statement period. These snapshots don't change afterwards, so they show the plan exactly as it was when that statement was produced. Use them to render statements and to reconcile a statement with the plans behind it.
Details
Lifecycle of a plan
- A statement closes with a balance that's left unpaid. That balance (principal, interest, and fees) becomes the plan's
principal_amount. An enrollment fee is added on top asfee_amount, and the plan is split intonum_installmentsequal installments. The plan starts outACTIVE, andsource_idis the token of the statement it was opened from. - On each installment's
due_date, the installment is billed to the account anddate_assessedis set. It then appears in that cycle's statement and is owed by itspayment_due_date. - Payments to the account are applied to installments oldest first. Each payment is added to the installment's
payments, andamount_paidandamount_outstandingchange to match. - When every installment has been paid off, the plan moves to
FULLY_PAIDandclosed_atis set to the date of the last payment.
Sample responses
The samples below follow one plan. On August 31, a statement closes with $350.00 in purchases left unpaid. That balance is converted into a 3-installment plan with a 5% enrollment fee ($17.50), for a total of $367.50, or $122.50 per installment.
This sample was retrieved on November 3. Installment 0 was billed with the September 30 statement and paid on October 20. Installment 1 was billed on October 31 and is due November 25. Installment 2 hasn't been billed yet.
{
"token": "2xL9QmVt7RkPz3NcW8YbH1sJfDa",
"financial_account_token": "a6d2b9f1-3c47-4e0a-9b5d-2f8e1c7a4d63",
"state": "ACTIVE",
"source_type": "UNPAID_BALANCE",
"source_id": "2xKfR4pLw9TnB6VhQ2ZsC8mJdYe",
"source_amounts": {
"purchases": { "principal": 35000, "interest": 0, "fees": 0 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"principal_amount": 35000,
"fee_amount": 1750,
"installment_plan_total": 36750,
"total_paid": 12250,
"installment_plan_adjustment": 0,
"num_installments": 3,
"installments_paid": 1,
"installments_outstanding": 2,
"start_date": "2026-08-31",
"closed_at": null,
"created": "2026-08-31T06:12:44Z",
"updated": "2026-10-31T06:09:17Z",
"installments": [
{
"installment_num": 0,
"due_date": "2026-09-30",
"payment_due_date": "2026-10-25",
"date_assessed": "2026-09-30",
"amount_due": 12250,
"amount_due_details": {
"purchases": { "principal": 11667, "interest": 0, "fees": 583 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"amount_paid": 12250,
"amount_paid_details": {
"purchases": { "principal": 11667, "interest": 0, "fees": 583 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"amount_outstanding": 0,
"amount_outstanding_details": {
"purchases": { "principal": 0, "interest": 0, "fees": 0 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"installment_adjustment": 0,
"payments": [
{
"date": "2026-10-20",
"amount": 12250,
"amount_details": {
"purchases": { "principal": 11667, "interest": 0, "fees": 583 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"is_adjustment": false
}
]
},
{
"installment_num": 1,
"due_date": "2026-10-31",
"payment_due_date": "2026-11-25",
"date_assessed": "2026-10-31",
"amount_due": 12250,
"amount_due_details": {
"purchases": { "principal": 11667, "interest": 0, "fees": 583 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"amount_paid": 0,
"amount_paid_details": {
"purchases": { "principal": 0, "interest": 0, "fees": 0 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"amount_outstanding": 12250,
"amount_outstanding_details": {
"purchases": { "principal": 11667, "interest": 0, "fees": 583 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"installment_adjustment": 0,
"payments": []
},
{
"installment_num": 2,
"due_date": "2026-11-30",
"payment_due_date": "2026-12-25",
"date_assessed": null,
"amount_due": 12250,
"amount_due_details": {
"purchases": { "principal": 11666, "interest": 0, "fees": 584 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"amount_paid": 0,
"amount_paid_details": {
"purchases": { "principal": 0, "interest": 0, "fees": 0 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"amount_outstanding": 12250,
"amount_outstanding_details": {
"purchases": { "principal": 11666, "interest": 0, "fees": 584 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"installment_adjustment": 0,
"payments": []
}
]
}Installment plan object
Returned by the get and list plan endpoints.
| Attribute | Type | Meaning |
|---|---|---|
token | string | Unique identifier for the plan. |
financial_account_token | UUID | The account the plan belongs to. |
state | enum | See Plan states. |
source_type | enum | What the plan was opened from. See Source types. |
source_id | string | The record the plan was opened from. For UNPAID_BALANCE, this is the statement token. |
source_amounts | object | null | The opening balance by category. See Category breakdowns. null means no breakdown was recorded, which is different from a breakdown of all zeros. |
principal_amount | integer | The balance the plan was opened on, not including the fee. |
fee_amount | integer | The one-time enrollment fee charged when the plan was opened. |
installment_plan_total | integer | principal_amount + fee_amount, the full amount the plan is scheduled to collect. It doesn't change after the plan opens. |
total_paid | integer | Amount applied to the plan so far, including adjustment credits. Equal to the sum of the installments' amount_paid. |
installment_plan_adjustment | integer | Total credited to the plan by recalculations. This credit reduces what's owed without changing installment_plan_total. |
num_installments | integer | How many installments the plan is split into. |
installments_paid | integer | How many installments have amount_outstanding of 0. |
installments_outstanding | integer | num_installments - installments_paid. This includes installments that haven't been billed yet, not just past-due ones. |
start_date | date | The date the plan was opened. |
closed_at | date | null | The date the plan was paid off or cancelled. null while the plan is open. |
created / updated | timestamp | When the plan was created and last changed. |
installments | array | The plan's installments, in order. See below. |
Installment
| Attribute | Type | Meaning |
|---|---|---|
installment_num | integer | The installment's position in the plan, starting at 0. |
due_date | date | The statement cycle this installment is billed on. |
payment_due_date | date | The date the installment must be paid by. It's that cycle's payment due date, and the installment is past due after it. |
date_assessed | date | null | The date the installment was actually billed to the account. null until it's billed. |
amount_due | integer | The installment's scheduled amount. The installments' amount_due values add up to installment_plan_total. |
amount_paid | integer | Amount applied to this installment, including adjustment credits. |
amount_outstanding | integer | amount_due - amount_paid, the amount still owed on this installment. |
installment_adjustment | integer | The part of amount_paid that came from recalculation credits rather than money received. |
amount_due_details / amount_paid_details / amount_outstanding_details | object | The same three amounts split by category. See Category breakdowns. |
payments | array | Each amount applied to this installment, oldest first. |
Installment payment
| Attribute | Type | Meaning |
|---|---|---|
date | date | The date the amount was applied. |
amount | integer | The amount applied to this installment. A single account payment can be split across several installments, so this is only the part this installment received. |
amount_details | object | amount split by category. |
is_adjustment | boolean | true when the amount is a recalculation credit rather than money received. |
Plan states
| State | Meaning |
|---|---|
ACTIVE | Open, with installments still owed. |
REBUILD_IN_PROGRESS | Open, and the account's history is being recalculated. This state is temporary, and the plan returns to ACTIVE or closes when the recalculation finishes. When you list plans, ?state=ACTIVE also returns plans in this state. |
FULLY_PAID | Every installment has been paid off. closed_at is set. |
CANCELLED | The plan was closed without being paid off. closed_at is set. |
PENDING | Reserved. No plans are created in this state today. |
Source types
source_type | Meaning |
|---|---|
UNPAID_BALANCE | The plan was opened from a balance a statement left unpaid. source_id is that statement's token, and an account gets at most one plan per statement. |
TRANSACTION | Reserved for plans opened from a single transaction (Buy Now, Pay Later). This is not yet supported in production, but will be in early 2027 |
Category breakdowns
Every *_details field and source_amounts breaks an amount down in two ways. The first level is the kind of balance: purchases, cash_advances, or balance_transfers. Inside each kind, the amount is split into principal, interest, and fees. The values in a breakdown always add up to the amount it describes. For example, the values in amount_due_details add up to amount_due. This means a plan keeps the same category split as the balance it was opened from. The enrollment fee is counted under fees.
This is the same plan as it stood on the statement that closed September 30. Compare it with the live plan above:
- Installment 0 was billed that day, so
date_assessedis set. It wasn't paid until October 20, so on this snapshot it still showsamount_outstanding: 12250and no payments. - Installment 1 hadn't been billed yet, so its
date_assessedisnull. total_paidandinstallments_paidare0, andupdatedis the plan's last change before this statement was generated.
token is the statement token, and installment_plan_token is the plan token.
{
"token": "2yA3HcNp6WqLs1TgK9VxD4rMbZu",
"installment_plan_token": "2xL9QmVt7RkPz3NcW8YbH1sJfDa",
"state": "ACTIVE",
"source_type": "UNPAID_BALANCE",
"source_id": "2xKfR4pLw9TnB6VhQ2ZsC8mJdYe",
"source_amounts": {
"purchases": { "principal": 35000, "interest": 0, "fees": 0 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"principal_amount": 35000,
"fee_amount": 1750,
"installment_plan_total": 36750,
"total_paid": 0,
"installment_plan_adjustment": 0,
"num_installments": 3,
"installments_paid": 0,
"installments_outstanding": 3,
"start_date": "2026-08-31",
"closed_at": null,
"created": "2026-08-31T06:12:44Z",
"updated": "2026-09-30T06:10:02Z",
"installments": [
{
"installment_num": 0,
"due_date": "2026-09-30",
"payment_due_date": "2026-10-25",
"date_assessed": "2026-09-30",
"amount_due": 12250,
"amount_due_details": {
"purchases": { "principal": 11667, "interest": 0, "fees": 583 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"amount_paid": 0,
"amount_paid_details": {
"purchases": { "principal": 0, "interest": 0, "fees": 0 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"amount_outstanding": 12250,
"amount_outstanding_details": {
"purchases": { "principal": 11667, "interest": 0, "fees": 583 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"installment_adjustment": 0,
"payments": []
},
{
"installment_num": 1,
"due_date": "2026-10-31",
"payment_due_date": "2026-11-25",
"date_assessed": null,
"amount_due": 12250,
"amount_due_details": {
"purchases": { "principal": 11667, "interest": 0, "fees": 583 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"amount_paid": 0,
"amount_paid_details": {
"purchases": { "principal": 0, "interest": 0, "fees": 0 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"amount_outstanding": 12250,
"amount_outstanding_details": {
"purchases": { "principal": 11667, "interest": 0, "fees": 583 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"installment_adjustment": 0,
"payments": []
},
{
"installment_num": 2,
"due_date": "2026-11-30",
"payment_due_date": "2026-12-25",
"date_assessed": null,
"amount_due": 12250,
"amount_due_details": {
"purchases": { "principal": 11666, "interest": 0, "fees": 584 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"amount_paid": 0,
"amount_paid_details": {
"purchases": { "principal": 0, "interest": 0, "fees": 0 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"amount_outstanding": 12250,
"amount_outstanding_details": {
"purchases": { "principal": 11666, "interest": 0, "fees": 584 },
"cash_advances": { "principal": 0, "interest": 0, "fees": 0 },
"balance_transfers": { "principal": 0, "interest": 0, "fees": 0 }
},
"installment_adjustment": 0,
"payments": []
}
]
}A statement snapshot is the plan as it stood when a given statement was generated. It has the same fields as the plan, with two differences:
tokenis the token of the statement the snapshot belongs to. A plan has at most one snapshot per statement, so the statement token identifies the snapshot. Use it as the{statement_token}path parameter and as the pagination cursor.installment_plan_tokenholds the plan's own token. There is nofinancial_account_token, because the account is already in the path.
All other fields mean the same thing as on the live plan, but their values are as of that statement. On a snapshot, total_paid, installments_paid, date_assessed, payments, closed_at, and state reflect only what had happened by the time that statement was generated.
Which statements carry a snapshot. A plan gets a snapshot on every statement whose period it was open for. That means the plan started on or before the period ended and wasn't closed before the period began. A plan that is paid off during a period gets one last snapshot showing it FULLY_PAID, and it doesn't appear on later statements.
List filters
GET .../installment_plans/{installment_plan_token}/statements returns snapshots oldest first and accepts these query parameters:
| Parameter | Meaning |
|---|---|
begin / end | Only snapshots whose statement starts on or after begin, or on or before end. |
state | Only snapshots in which the plan was in this state, such as FULLY_PAID to find the statement where the plan closed. |
starting_after / ending_before | Statement tokens to use as pagination cursors. |
page_size | 1 to 100. Default 50. |
GET .../installment_plans takes state and the same cursor and page_size parameters, and uses plan tokens as cursors.
Errors
| Situation | Status | Message |
|---|---|---|
installment_plan_token isn't a valid token | 400 | Incorrectly formatted installment_plan_token |
statement_token isn't a valid token | 400 | Incorrectly formatted statement_token |
| Cursor isn't within the requested range | 400 | starting_after or ending_before is not in range |
| Plan not found on this account | 404 | Installment plan not found |
| No snapshot of this plan exists on that statement | 404 | Installment plan statement not found |
Release Timeline
October 27, 2026
User Impact
No impact to existing users. Programs looking to add installment plans to their credit configurations should reach out to Lithic Implementations
Updated Documentation
See here for a further guide to Installment Plans
If you have any questions or concerns, please contact us via the HELP link in your Lithic Dashboard.
The Lithic changelog has an RSS feed! To monitor for new update announcements, subscribe with your preferred RSS reader.
