Companies
Company borrower retention (weekly snapshot)
How well a company keeps its borrowers when they refinance: kept (refinanced again by ANY LO at the company) vs lost to other companies, with the capturing companies and LOs, timing, the trend, a verdict, and per-LO retention for the company's own loan officers. Precomputed weekly — computedAt says when. 404 means not computed (no loans since 2017, or not reached yet), never zero retention.
Authorization
Path parameters
nmlsIdstringrequiredCompany NMLS ID
Query parameters
windowenumdefault: "last12Months"last12Months (the trailing 12 months to the computation date, with the 12 months before as previous) or allTime (2017-01-01 on). Default last12Months.
last12MonthsallTimeResponses
200objectThe stored snapshotShow attributesHide attributes
activeListingsobject | nullrequiredRetained borrowers listed for sale now, on loans by the company's own LOs: the count and top LOs (rows: GET /companies/{nmlsId}/retention/active-listings). Same for every window. Null until the weekly batch has checked listings for this company.
Show child attributesHide child attributes
computedAtstringrequiredWhen the listings were checked (ISO-8601) — the run that wrote the rows. Listings are as of this time, not live.
parcelsCheckedintegerrequiredRetained parcels whose latest company loan was written by an LO the company employed on it — the population checked for listings.
statusenumrequiredtimeout: the listing check did not finish in this run, so the previous run's rows and counts are kept (or none, on a first run).
oktimeoutteamobject | nullThe current-team view's counts; null until the batch has checked it for this company.
Show child attributesHide child attributes
rosterintegerrequiredCurrent LOs (active sponsorships) checked.
statusenumrequiredoktimeouttotalintegerrequiredRows in view=team: listings on loans by the company's current LOs, written at the company or at a previous employer.
writtenElsewhereintegerrequiredOf those, loans the LOs wrote at a previous employer.
topOriginatorsobject[]requiredTop 10 LOs by active listings.
Show child attributesHide child attributes
countintegerrequirednamestringrequirednmlsIdstringrequiredtotalintegerrequiredRetained borrowers whose home is listed for sale right now, on loans written by the company's own LOs.
bookobjectrequiredRows the computation read (sizing / provenance).
Show child attributesHide child attributes
laterLoansnumberrequiredownLoansnumberrequiredparcelsnumberrequiredsalesnumberrequiredcapturingCompaniesobject[]requiredTop 10 companies that captured lost borrowers, by volume.
Show child attributesHide child attributes
countnumberrequiredlaneenumrequiredown_companyservicercompetitornamestringrequirednmlsIdstringrequiredvolumenumberrequiredcapturingOriginatorsobject[]requiredTop 10 LOs that captured lost borrowers, by volume.
Show child attributesHide child attributes
companyNamestringrequiredcountnumberrequirednamestringrequirednmlsIdstringrequiredvolumenumberrequiredcapturingTotalsobjectrequiredShow child attributesHide child attributes
companiesobjectrequiredShow child attributesHide child attributes
distinctnumberrequiredloansnumberrequiredvolumenumberrequiredoriginatorsobjectrequiredShow child attributesHide child attributes
distinctnumberrequiredloansnumberrequiredunattributedLoansnumberrequiredvolumenumberrequiredchurnTrendobject[]requiredShow child attributesHide child attributes
churnednumberrequiredkeptnumberrequiredmonthstringrequiredretainednumberrequiredsecondPositionsnumberrequiredcompanyNamestring | nullrequiredcompanyNmlsIdstringrequiredcomputedAtstringrequiredWhen the weekly batch computed this snapshot (ISO-8601).
lanesobjectrequiredWhere lost refinances went: the borrower's funding lender (servicer) or another company (competitor). own_company is always 0 at company level (those are kept).
Show child attributesHide child attributes
competitorobjectrequiredShow child attributesHide child attributes
countnumberrequiredvolumenumberrequiredown_companyobjectrequiredShow child attributesHide child attributes
countnumberrequiredvolumenumberrequiredservicerobjectrequiredShow child attributesHide child attributes
countnumberrequiredvolumenumberrequiredlikelyToSellobject | nullrequiredRetained borrowers likely to list their home for sale (likely-to-list score 90+, not listed now), on loans by the company's own LOs: the count and top LOs (rows: GET /companies/{nmlsId}/retention/likely-to-sell). Same for every window. Null until the weekly batch has checked this company.
Show child attributesHide child attributes
computedAtstringrequiredWhen the batch checked these borrowers (ISO-8601) — the run that wrote the rows. As of this time, not live.
parcelsCheckedintegerrequiredRetained parcels whose latest company loan was written by an LO the company employed on it — the population checked (the same one active listings checks).
parcelsScoredintegerrequiredOf those, parcels with a likely-to-list score on file. A parcel without one is unknown, not unlikely.
statusenumrequiredtimeout: the check did not finish in this run, so the previous run's rows and counts are kept (or none, on a first run).
oktimeoutteamobject | nullThe current-team view's counts; null until the batch has checked it for this company.
Show child attributesHide child attributes
rosterintegerrequiredCurrent LOs (active sponsorships) checked.
statusenumrequiredoktimeouttotalintegerrequiredRows in view=team: borrowers likely to list on loans by the company's current LOs, written at the company or at a previous employer.
writtenElsewhereintegerrequiredOf those, loans the LOs wrote at a previous employer.
topOriginatorsobject[]requiredTop 10 LOs by borrowers likely to list.
Show child attributesHide child attributes
countintegerrequirednamestringrequirednmlsIdstringrequiredtotalintegerrequiredRetained borrowers, on loans written by the company's own LOs, whose home has a likely-to-list score of 90 or more and is not listed for sale or under contract now.
originatorRetentionobject[]requiredRefinance retention for the company's own loan officers, ranked by borrowers who refinanced at another company (top 10; only LOs with at least 10 refi events in the window).
Show child attributesHide child attributes
churnedCountnumberrequiredTheir borrowers who refinanced at another company.
churnedVolumenumberrequiredkeptCountnumberrequiredTheir borrowers the company refinanced again (any LO).
namestringrequirednmlsIdstringrequiredrefiRetentionRatenumber | nullrequiredverdictenumrequiredOn refiRetentionRate (kept ÷ (kept + churned) refi events): quiet under 10 events, holding ≥ 60%, leaking 35–60%, bleeding < 35% — the LO tab's thresholds.
holdingleakingbleedingquietperiodobjectrequiredShow child attributesHide child attributes
endstringrequiredLast day (UTC, inclusive).
startstringrequiredFirst day (UTC).
previousobject | nullrequiredThe preceding period of equal length (for deltas); null for allTime.
Show child attributesHide child attributes
periodobjectrequiredShow child attributesHide child attributes
endstringrequiredLast day (UTC, inclusive).
startstringrequiredFirst day (UTC).
summaryobjectrequiredShow child attributesHide child attributes
churnRatenumberrequiredchurnedCountnumberrequireddaysToRefiPairsUsednumberrequiredkeptRefiCountnumberrequiredSame-LO refinances of the LO's own borrowers in the period
keptRefiVolumenumberrequiredkeptSecondCountnumberrequiredmedianDaysToRefinumber | nullrequiredpropertySoldCountnumberrequiredrefiRetentionRatenumber | nullrequiredkept ÷ (kept + churned) refi events; null with none
retainedCountnumberrequiredsecondPositionCountnumberrequiredsecondPositionVolumenumberrequiredtotalBorrowersnumberrequiredunattributedCountnumberrequiredvolumeLostnumberrequiredvolumeRetainednumberrequiredverdictenumrequiredOn refiRetentionRate (kept ÷ (kept + churned) refi events): quiet under 10 events, holding ≥ 60%, leaking 35–60%, bleeding < 35% — the LO tab's thresholds.
holdingleakingbleedingquietschemaVersionintegerrequiredsecondPositionLanesobjectrequiredShow child attributesHide child attributes
competitorobjectrequiredShow child attributesHide child attributes
countnumberrequiredvolumenumberrequiredown_companyobjectrequiredShow child attributesHide child attributes
countnumberrequiredvolumenumberrequiredservicerobjectrequiredShow child attributesHide child attributes
countnumberrequiredvolumenumberrequiredstatusenumrequiredtruncated: a loan / sale scan hit its row cap, so counts cover the rows read. timeout: the book could not be read within the batch's per-company budget — every count is 0 and means 'not available', not 'none'.
oktimeouttruncatedsummaryobjectrequiredSame fields as the LO report. At company level a refinance by ANY LO at the company is kept; only a refinance at another company is churned.
Show child attributesHide child attributes
churnRatenumberrequiredchurnedCountnumberrequireddaysToRefiPairsUsednumberrequiredkeptRefiCountnumberrequiredSame-LO refinances of the LO's own borrowers in the period
keptRefiVolumenumberrequiredkeptSecondCountnumberrequiredmedianDaysToRefinumber | nullrequiredpropertySoldCountnumberrequiredrefiRetentionRatenumber | nullrequiredkept ÷ (kept + churned) refi events; null with none
retainedCountnumberrequiredsecondPositionCountnumberrequiredsecondPositionVolumenumberrequiredtotalBorrowersnumberrequiredunattributedCountnumberrequiredvolumeLostnumberrequiredvolumeRetainednumberrequiredtimingobjectrequiredShow child attributesHide child attributes
cashOutCountnumberrequiredcashOutSharenumber | nullrequiredloanTypeChangeCountnumberrequiredmedianMonthsnumber | nullrequiredmonthsToExitobject[]requiredShow child attributesHide child attributes
bucketstringrequiredcountnumberrequiredrateDeltaMediannumber | nullrequiredrateDeltaPairsnumberrequiredverdictenumrequiredOn refiRetentionRate (kept ÷ (kept + churned) refi events): quiet under 10 events, holding ≥ 60%, leaking 35–60%, bleeding < 35% — the LO tab's thresholds.
holdingleakingbleedingquietwindowenumrequiredlast12MonthsallTime400objectValidation error401objectUnauthorized403objectForbidden (authenticated, but missing required context — e.g. no active organization)404objectNot found413objectResponse payload too large — detail endpoint capped to fit Lambda response limits503objectSearch timed out or the cluster is overloaded — retry after `Retry-After` seconds.