Model MatchHelp

Originators

Borrower retention report for this LO

postapi.modelmatch.com/v1/originators/{nmlsId}/retention

Classifies every loan this LO originated since 2017 against every later loan and sale on the same parcel, for the period start–end: borrowers kept (the LO refinanced them again), lost (refinanced elsewhere — churnedLoans, with who captured them), sold, or a second lien taken elsewhere. Returns the summary, capture lanes (same funding lender vs other companies), capturing companies / LOs (top 25 + full-population totals), timing, monthly trend, the newest 500 loss rows, and exit signals on the retained book (atRisk). compare adds a second period's summary and monthly trend (previous) from the same scan. A very large book that cannot be read in time answers status: "timeout".

Authorization

x-api-keystringrequired

API key or OAuth token. See Authentication.

Path parameters

nmlsIdstringrequired

Originator NMLS ID

Body application/json

compareobject

Optional comparison period (e.g. the prior 14 months). Its summary and monthly trend come back as previous; it reuses this request's loan scan, so it costs no extra search.

Show child attributes
endstringrequired

Last day of the period (UTC, inclusive).

startstringrequired

First day of the period (UTC).

endstringrequired

Last day of the period (UTC, inclusive).

includeAtRiskboolean

Scan the retained book for exit signals (listed / likely to sell / rate incentive). Default true.

startstringrequired

First day of the period (UTC).

Responses

200objectRetention report
Show attributes
atRiskobject | nullrequired

Exit signals on the retained book; null when not requested or the scan could not complete.

Show child attributes
equityBandsobject[]required
Show child attributes
bandstringrequired
countnumberrequired
highEquityLowRatenumberrequired
joinednumberrequired
likelyToSellnumberrequired
listedNownumberrequired
medianEquityPctnumber | nullrequired
medianRatenumber | nullrequired
rateIncentivenumberrequired
retainedScannednumberrequired
rowsobject[]required
Show child attributes
addressstringrequired
borrowerstringrequired
currentBalancenumber | nullrequired
currentLenderstring | nullrequired
currentRatenumber | nullrequired
equityPctnumber | nullrequired
flagsenum[]required
Options:listedlikely_sellrate
homeValuenumber | nullrequired
listPricenumber | nullrequired
listedDatenumber | nullrequired
listingStatusstring | nullrequired
originalAmountnumberrequired
originalLoanDatenumberrequired
originalLoanTypestringrequired
propensityCategorystring | nullrequired
propertyIdstringrequired
salePropensitynumber | nullrequired
signallingnumberrequired
capturingCompaniesobject[]required
Show child attributes
countnumberrequired
laneenumrequired
Options:own_companyservicercompetitor
namestringrequired
nmlsIdstringrequired
volumenumberrequired
capturingOriginatorsobject[]required
Show child attributes
companyNamestringrequired
countnumberrequired
namestringrequired
nmlsIdstringrequired
volumenumberrequired
capturingTotalsobjectrequired
Show child attributes
companiesobjectrequired
Show child attributes
distinctnumberrequired
loansnumberrequired
volumenumberrequired
originatorsobjectrequired
Show child attributes
distinctnumberrequired
loansnumberrequired
unattributedLoansnumberrequired
volumenumberrequired
secondCompaniesobjectrequired
Show child attributes
distinctnumberrequired
loansnumberrequired
volumenumberrequired
churnByLoanTypeobject[]required
Show child attributes
countnumberrequired
typestringrequired
volumenumberrequired
churnTrendobject[]required
Show child attributes
churnednumberrequired
keptnumberrequired
monthstringrequired
retainednumberrequired
secondPositionsnumberrequired
churnedLoansobject[]required
Show child attributes
addressstringrequired
borrowerstringrequired
capturingAmountnumberrequired
capturingCompanystringrequired
capturingCompanyNmlsIdstringrequired
capturingLenderstringrequired
capturingLoNamestringrequired
capturingLoNmlsIdstringrequired
capturingLoanTypestringrequired
capturingRatenumber | nullrequired
cashOutbooleanrequired
currentobject | nullrequired

What the parcel looks like today, when a scored snapshot newer than the event joined; null otherwise (unknown, never 'retained').

Show child attributes
currentBalancenumber | nullrequired
currentLenderstring | nullrequired
currentRatenumber | nullrequired
lastSaleDatenumber | nullrequired
loStillActivebooleanrequired
ownerChangedboolean | nullrequired
daysToEventnumberrequired
eventDatenumberrequired
kindenumrequired
Options:refisecond
laneenumrequired
Options:own_companyservicercompetitor
originalAmountnumberrequired
originalLenderstringrequired
originalLoanDatenumberrequired
originalLoanTypestringrequired
originalRatenumber | nullrequired
originalTransactionTypestringrequired
propertyIdstringrequired
sameBorrowerboolean | nullrequired
lanesobjectrequired
Show child attributes
competitorobjectrequired
Show child attributes
countnumberrequired
volumenumberrequired
own_companyobjectrequired
Show child attributes
countnumberrequired
volumenumberrequired
servicerobjectrequired
Show child attributes
countnumberrequired
volumenumberrequired
previousobject | nullrequired

The compare period's summary and monthly trend, when asked.

Show child attributes
churnTrendobject[]required
Show child attributes
churnednumberrequired
keptnumberrequired
monthstringrequired
retainednumberrequired
secondPositionsnumberrequired
summaryobjectrequired
Show child attributes
churnRatenumberrequired
churnedCountnumberrequired
daysToRefiPairsUsednumberrequired
keptRefiCountnumberrequired

Same-LO refinances of the LO's own borrowers in the period

keptRefiVolumenumberrequired
keptSecondCountnumberrequired
medianDaysToRefinumber | nullrequired
propertySoldCountnumberrequired
refiRetentionRatenumber | nullrequired

kept ÷ (kept + churned) refi events; null with none

retainedCountnumberrequired
secondPositionCountnumberrequired
secondPositionVolumenumberrequired
totalBorrowersnumberrequired
unattributedCountnumberrequired
volumeLostnumberrequired
volumeRetainednumberrequired
secondPositionCompaniesobject[]required
Show child attributes
countnumberrequired
laneenumrequired
Options:own_companyservicercompetitor
namestringrequired
nmlsIdstringrequired
volumenumberrequired
secondPositionLanesobjectrequired
Show child attributes
competitorobjectrequired
Show child attributes
countnumberrequired
volumenumberrequired
own_companyobjectrequired
Show child attributes
countnumberrequired
volumenumberrequired
servicerobjectrequired
Show child attributes
countnumberrequired
volumenumberrequired
statusenumrequired

timeout when the LO's loan history could not be read within the time budget (very large book): every count is then 0 and means 'not available', not 'none'.

Options:oktimeout
summaryobjectrequired
Show child attributes
churnRatenumberrequired
churnedCountnumberrequired
daysToRefiPairsUsednumberrequired
keptRefiCountnumberrequired

Same-LO refinances of the LO's own borrowers in the period

keptRefiVolumenumberrequired
keptSecondCountnumberrequired
medianDaysToRefinumber | nullrequired
propertySoldCountnumberrequired
refiRetentionRatenumber | nullrequired

kept ÷ (kept + churned) refi events; null with none

retainedCountnumberrequired
secondPositionCountnumberrequired
secondPositionVolumenumberrequired
totalBorrowersnumberrequired
unattributedCountnumberrequired
volumeLostnumberrequired
volumeRetainednumberrequired
timingobjectrequired
Show child attributes
cashOutCountnumberrequired
cashOutSharenumber | nullrequired
loanTypeChangeCountnumberrequired
medianMonthsnumber | nullrequired
monthsToExitobject[]required
Show child attributes
bucketstringrequired
countnumberrequired
rateDeltaMediannumber | nullrequired
rateDeltaPairsnumberrequired
truncatedbooleanrequired

A loan / sale scan hit its row cap; counts cover the rows read.

400objectValidation error
401objectUnauthorized
403objectForbidden (authenticated, but missing required context — e.g. no active organization)
404objectNot found
413objectResponse payload too large — detail endpoint capped to fit Lambda response limits
503objectSearch timed out or the cluster is overloaded — retry after `Retry-After` seconds.