---
title: "Compare repayment scenarios side-by-side"
method: POST
path: "/v1/comparison"
tags: ["Finology.PublicApi"]
---

# Compare repayment scenarios side-by-side

`POST /v1/comparison`

## Request

- Base URL: `https://api.finology.tech` (the document declares no server; this is the origin it was published from)
- URL: `https://api.finology.tech/v1/comparison`
- Auth: API key in header `X-Api-Key`

Runs several scenarios (commonly the same loans under different plans) and returns each verified projection plus the engine-decided lowest-total-cost label: the arm with the lowest totalOutOfPocket + forgivenessTaxesOwed. Calc-only. Send "includeYearly": true to add `yearly` to each projection: year 0 is the loan book as sent; year n covers repayment months 12(n-1) to 12n-1 and gives the principal and interest balance after that year's last payment, the payments that year, the cumulative paid and any balance forgiven that year (date = that month). The series ends at the payoff or forgiveness month. Payments sum to totalOutOfPocket and forgiven amounts to amountForgiven. Money in cents. Default false: the field is then absent and the response is unchanged. A plan whose answer is an artifact of the prior-month count (nothing left to pay, the whole balance in one payment, or forgiveness before any payment) is a 400 naming the plan, the same plans the free calculator at /v1/calculators/loan leaves out.

## Request body

- ComparisonRequest
  - `arms` ComparisonArm[], required
    - `scenario` ScenarioRequest, required
      - `planType` string, required
      - `adjustedGrossIncome` number, double, required
      - `spouseAdjustedGrossIncome` number, double, nullable
      - `spouseFederalLoanBalance` number, double, nullable
      - `filingStatus` string, required
      - `dependents` integer, required
      - `state` string, required
      - `workingTowardsPslf` boolean, required
      - `annualIncomeGrowth` number, double
      - `label` string, nullable
    - `loans` LoanRequest[], required
      - `loanType` string, required
      - `principalBalance` number, double, required
      - `interestBalance` number, double
      - `interestRate` number, double, required
      - `disbursedAmount` number, double
      - `idrMonthsInRepayment` integer
      - `pslfCount` integer
  - `includeYearly` boolean: Optional, default false. Send "includeYearly": true to add `yearly` to each projection: year 0 is the loan book as sent; year n covers repayment months 12(n-1) to 12n-1 and gives the principal and interest balance after that year's last payment, the payments that year, the cumulative paid and any balance forgiven that year (date = that month). The series ends at the payoff or forgiveness month. Payments sum to totalOutOfPocket and forgiven amounts to amountForgiven. Money in cents. Default false: the field is then absent and the response is unchanged.

## Response `200`

OK

- ScenarioComparisonResult
  - `projections` ProjectionResult[], nullable
    - `label` string, nullable
    - `planType` string, nullable
    - `year1MonthlyPayment` number, double
    - `payoffOrForgivenessDate` string, date-time, nullable
    - `monthsToFinish` integer, nullable
    - `totalOutOfPocket` number, double
    - `amountForgiven` number, double
    - `forgivenessTaxesOwed` number, double
    - `forgivenessType` 'Pslf' | 'TimeBased' | 'Teacher' | 'None': Which forgiveness program the projection reaches: Pslf, TimeBased, Teacher or None. Keyed routes wrote the integer before 2026-10-14; that value is still sent as forgivenessTypeCode (0 Pslf, 1 TimeBased, 2 Teacher, 3 None), deprecated.
    - `forgivenessTypeCode` integer
    - `weightedAverageInterestRate` number, double
    - `yearly` YearlyPoint[], nullable: Present only when the request sent includeYearly: true. Send "includeYearly": true to add `yearly` to each projection: year 0 is the loan book as sent; year n covers repayment months 12(n-1) to 12n-1 and gives the principal and interest balance after that year's last payment, the payments that year, the cumulative paid and any balance forgiven that year (date = that month). The series ends at the payoff or forgiveness month. Payments sum to totalOutOfPocket and forgiven amounts to amountForgiven. Money in cents. Default false: the field is then absent and the response is unchanged.
      - `year` integer: 0 for the opening balance, then 1, 2, ... per year of repayment.
      - `date` string, date-time: The month the balances are read.
      - `principalBalance` number, double: Outstanding principal across the loan book at date.
      - `interestBalance` number, double: Outstanding unpaid interest across the loan book at date.
      - `paymentsThisYear` number, double: What the borrower paid during this year (0 for year 0).
      - `cumulativePaid` number, double: Paid from the repayment start through this year. The last point equals totalOutOfPocket.
      - `forgivenThisYear` number, double: Balance forgiven during this year; sums to amountForgiven.
    - `provenance` EngineProvenance
      - `computedBy` string, nullable
      - `engine` string, nullable
      - `parityVerified` boolean
      - `computedAtUtc` string, date-time
      - `ruleVersion` string, nullable
      - `citations` RuleCitation[], nullable
        - `id` string, nullable
        - `label` string, nullable
        - `authority` string, nullable
        - `url` string, nullable
        - `effectiveDate` string, nullable
        - `lastVerified` string, nullable
      - `knownOmissions` RuleOmissionNote[], nullable
        - `id` string, nullable
        - `label` string, nullable
        - `detail` string, nullable
        - `authority` string, nullable
        - `url` string, nullable
        - `effectiveDate` string, nullable
        - `expiresDate` string, nullable
        - `lastVerified` string, nullable
      - `answerId` string, uuid, nullable
      - `verifyUrl` string, nullable
  - `lowestCostLabel` string, nullable
  - `provenance` EngineProvenance
    - `computedBy` string, nullable
    - `engine` string, nullable
    - `parityVerified` boolean
    - `computedAtUtc` string, date-time
    - `ruleVersion` string, nullable
    - `citations` RuleCitation[], nullable
      - `id` string, nullable
      - `label` string, nullable
      - `authority` string, nullable
      - `url` string, nullable
      - `effectiveDate` string, nullable
      - `lastVerified` string, nullable
    - `knownOmissions` RuleOmissionNote[], nullable
      - `id` string, nullable
      - `label` string, nullable
      - `detail` string, nullable
      - `authority` string, nullable
      - `url` string, nullable
      - `effectiveDate` string, nullable
      - `expiresDate` string, nullable
      - `lastVerified` string, nullable
    - `answerId` string, uuid, nullable
    - `verifyUrl` string, nullable

## Other responses

- `400`: Bad Request

---

[API](https://skmtc.dev/finology/apis/finology-public-api.md) · [All operations](https://skmtc.dev/finology/apis/finology-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/finology/apis/finology-public-api/revisions/ed0522429715?raw)
