Model MatchHelp

Market

Market metrics over time

postapi.modelmatch.com/v1/market/analytics/time-series

Authorization

x-api-keystringrequired

API key or OAuth token. See Authentication.

Body application/json

advancedFiltersone of
Show child attributes
Option 1object
Show child attributes
childrenone of[]required

Array of filter expressions (AND)

Same shape as its parent.

typeenumrequired
Options:and
Option 2object
Show child attributes
childrenone of[]required

Array of filter expressions (OR)

Same shape as its parent.

typeenumrequired
Options:or
Option 3object
Show child attributes
childone ofrequired

Same shape as its parent.

typeenumrequired
Options:not
Option 4object
Show child attributes
fieldstringrequired
openumrequired

Comparison operator. exists means the field has a REAL value: on fields whose source records an unknown as an in-domain value (e.g. beds, squareFeet, lotSquareFeet, where an unrecorded measurement is stored as 0), those docs count as NOT existing. neq keeps docs with no value — it removes only what is known to equal the value, matching the reading of an exclusion.

Options:eqneqgtgteltltebetweeninmatchgeoDistanceexists
typeenumrequired
Options:filter
valuenull

Comparison value

filtersone of
Show child attributes
Option 1object
Show child attributes
childrenone of[]required

Array of filter expressions (AND)

Same shape as its parent.

typeenumrequired
Options:and
Option 2object
Show child attributes
childrenone of[]required

Array of filter expressions (OR)

Same shape as its parent.

typeenumrequired
Options:or
Option 3object
Show child attributes
childone ofrequired

Same shape as its parent.

typeenumrequired
Options:not
Option 4object
Show child attributes
fieldstringrequired
openumrequired

Comparison operator. exists means the field has a REAL value: on fields whose source records an unknown as an in-domain value (e.g. beds, squareFeet, lotSquareFeet, where an unrecorded measurement is stored as 0), those docs count as NOT existing. neq keeps docs with no value — it removes only what is known to equal the value, matching the reading of an exclusion.

Options:eqneqgtgteltltebetweeninmatchgeoDistanceexists
typeenumrequired
Options:filter
valuenull

Comparison value

flatFiltersobject
Show child attributes
amortizationTypeone of | null
Show child attributes
Option 1string
Option 2string[]

Match any value

Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
appraisedValueone of | null
Show child attributes
Option 1number
Option 2number[]

Match any value

Option 3object

Numeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.

Show child attributes
gtnumber
gtenumber
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.

ltnumber
ltenumber
borrowerGenerationone of | null
Show child attributes
Option 1string
Option 2string[]

Match any value

Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
channelone of | null
Show child attributes
Option 1string
Option 2string[]

Match any value

Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
closingDateone of | null
Show child attributes
Option 1string

Exact date, or a whole period: YYYY-MM-DD (that day), YYYY-MM (the whole month — "2025-06" = 2025-06-01 through 2025-06-30) or YYYY (the whole year). YYYYMMDD, MM/DD/YYYY, an ISO-8601 datetime and epoch milliseconds are also accepted. An unparseable value is a 400.

Option 2object

Date range. Excludes null/missing-field docs by default; add includeNulls: true to keep them. Bounds accept YYYY, YYYY-MM, YYYY-MM-DD, YYYYMMDD, MM/DD/YYYY, a full ISO datetime or epoch milliseconds; an unparseable bound is a 400. A partial bound denotes the whole period and expands to the edge that preserves the operator: gte/lt take the period START, gt/lte take the period END — so {gte: "2024"} means on/after 2024-01-01 and {lte: "2024"} means through 2024-12-31.

Show child attributes
gtstring
gtestring
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires a bound.

ltstring
ltestring
combinedLtvone of | null
Show child attributes
Option 1number
Option 2number[]

Match any value

Option 3object

Numeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.

Show child attributes
gtnumber
gtenumber
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.

ltnumber
ltenumber
communityIncomeLevelone of | null

FFIEC income classification of the neighborhood the property sits in. A tract-level aggregate statistic describing the neighborhood, never an individual, household or applicant attribute. Carried on roughly a fifth of originations, so this filter narrows sharply.

Show child attributes
Option 1enum

One of (case-insensitive): low, moderate, middle, upper

Options:lowmoderatemiddleupper
Option 2enum[]

Match any of these values

Options:lowmoderatemiddleupper
Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
countyone of | null
Show child attributes
Option 1string
Option 2string[]

Match any value

Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
countyCodeone of | null

3-digit county code (the county segment of a FIPS, e.g. Philadelphia = "101"). Pair it with state — the code is not unique across states. county accepts a county NAME or 5-digit FIPS and resolves to this code for you.

Show child attributes
Option 1string
Option 2string[]

Match any value

Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
craEligibleboolean

Only CRA-eligible originations (a low- or moderate-income neighborhood OR a low- or moderate-income borrower). Determined on every origination.

creditScoreone of | null
Show child attributes
Option 1number
Option 2number[]

Match any value

Option 3object

Numeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.

Show child attributes
gtnumber
gtenumber
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.

ltnumber
ltenumber
currentHomeOwnerboolean | null
dtione of | null
Show child attributes
Option 1number
Option 2number[]

Match any value

Option 3object

Numeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.

Show child attributes
gtnumber
gtenumber
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.

ltnumber
ltenumber
dtifrontone of | null
Show child attributes
Option 1number
Option 2number[]

Match any value

Option 3object

Numeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.

Show child attributes
gtnumber
gtenumber
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.

ltnumber
ltenumber
firstTimeHomebuyerboolean | null
hmdaActionTakenone of | null
Show child attributes
Option 1string
Option 2string[]

Match any value

Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
incomeone of | null
Show child attributes
Option 1number
Option 2number[]

Match any value

Option 3object

Numeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.

Show child attributes
gtnumber
gtenumber
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.

ltnumber
ltenumber
loanAmountone of | null
Show child attributes
Option 1number
Option 2number[]

Match any value

Option 3object

Numeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.

Show child attributes
gtnumber
gtenumber
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.

ltnumber
ltenumber
loanApplicationDateone of | null
Show child attributes
Option 1string

Exact date, or a whole period: YYYY-MM-DD (that day), YYYY-MM (the whole month — "2025-06" = 2025-06-01 through 2025-06-30) or YYYY (the whole year). YYYYMMDD, MM/DD/YYYY, an ISO-8601 datetime and epoch milliseconds are also accepted. An unparseable value is a 400.

Option 2object

Date range. Excludes null/missing-field docs by default; add includeNulls: true to keep them. Bounds accept YYYY, YYYY-MM, YYYY-MM-DD, YYYYMMDD, MM/DD/YYYY, a full ISO datetime or epoch milliseconds; an unparseable bound is a 400. A partial bound denotes the whole period and expands to the edge that preserves the operator: gte/lt take the period START, gt/lte take the period END — so {gte: "2024"} means on/after 2024-01-01 and {lte: "2024"} means through 2024-12-31.

Show child attributes
gtstring
gtestring
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires a bound.

ltstring
ltestring
loanPurposeone of | null
Show child attributes
Option 1string
Option 2string[]

Match any value

Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
loanStatusone of | null

HMDA action, else funding/denial/lock date evidence.

Show child attributes
Option 1enum

One of (case-insensitive): funded, purchased, not_funded, pending

Options:fundedpurchasednot_fundedpending
Option 2enum[]

Match any of these values

Options:fundedpurchasednot_fundedpending
Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
loanTermone of | null
Show child attributes
Option 1number
Option 2number[]

Match any value

Option 3object

Numeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.

Show child attributes
gtnumber
gtenumber
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.

ltnumber
ltenumber
loanTypeone of | null
Show child attributes
Option 1string
Option 2string[]

Match any value

Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
lowModIncomeTractboolean

Only originations in a low- or moderate-income neighborhood. This describes the U.S. Census tract (neighborhood) as a whole — a tract-level aggregate statistic, never an individual, household or applicant attribute. false also matches originations whose neighborhood carries no income classification; pair with communityIncomeLevel when you need the classified population only.

ltvone of | null
Show child attributes
Option 1number
Option 2number[]

Match any value

Option 3object

Numeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.

Show child attributes
gtnumber
gtenumber
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.

ltnumber
ltenumber
majorityMinorityTractboolean

Only originations in a majority-minority neighborhood. This describes the U.S. Census tract (neighborhood) as a whole — a tract-level aggregate statistic, never an individual, household or applicant attribute. Carried on about half of originations.

metroone of | null

Metro area code (5-digit federal CBSA code, e.g. Los Angeles = "31084"). Roughly half of originations sit outside any metro area and carry no code, so a metro filter is a narrowing one.

Show child attributes
Option 1string
Option 2string[]

Match any value

Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
middleIncomeTractboolean

Only originations in a middle-income neighborhood. Tract-level aggregate, never an individual attribute. Same caveat on false as lowModIncomeTract.

minorityTractPctone of | null

Non-white share (0-100) of the neighborhood's population. Tract-level aggregate, never an individual attribute.

Show child attributes
Option 1number
Option 2number[]

Match any value

Option 3object

Numeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.

Show child attributes
gtnumber
gtenumber
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.

ltnumber
ltenumber
modeenum
Options:andor
noteRateone of | null
Show child attributes
Option 1number
Option 2number[]

Match any value

Option 3object

Numeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.

Show child attributes
gtnumber
gtenumber
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.

ltnumber
ltenumber
occupancyTypeone of | null
Show child attributes
Option 1string
Option 2string[]

Match any value

Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
propertyTypeone of | null
Show child attributes
Option 1string
Option 2string[]

Match any value

Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
purchasePriceone of | null
Show child attributes
Option 1number
Option 2number[]

Match any value

Option 3object

Numeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.

Show child attributes
gtnumber
gtenumber
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.

ltnumber
ltenumber
selfEmployedboolean | null
stateone of | null
Show child attributes
Option 1string
Option 2string[]

Match any value

Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
tractIncomeVsMetroPctone of | null

Neighborhood median family income as a percent of its metro area's — 100 is parity, and it legitimately exceeds 100. Tract-level aggregate, never an individual attribute.

Show child attributes
Option 1number
Option 2number[]

Match any value

Option 3object

Numeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.

Show child attributes
gtnumber
gtenumber
includeNullsboolean

Also keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.

ltnumber
ltenumber
veteranIndicatorboolean | null
zipone of | null
Show child attributes
Option 1string
Option 2string[]

Match any value

Option 3object

Fuzzy text match

Show child attributes
matchstringrequired
forecastobject

Append a zero-shot forecast (Amazon Chronos-2) to the time series. Monthly interval only. The history in current is returned unchanged; the forecast starts the month after forecast.asOf.

Show child attributes
horizonintegerdefault: 6

Months ahead to forecast, counted from asOf (1–12).

scenarioobjectdefault: {"rate30y":"hold"}

Known-future covariates the forecast conditions on. Omit for hold.

Show child attributes
rate30yone ofdefault: "hold"

Path of the 30-year fixed mortgage rate over the forecast horizon, one value per month, as a plain percent (6.5 = 6.5%). Presets: hold keeps the latest weekly Freddie Mac PMMS reading flat; fall glides it down 1.0 point linearly over the horizon; rise glides it up 1.0 point. An explicit array must have exactly horizon entries. The rate is an INPUT the model conditions on, never something it predicts.

Show child attributes
Option 1enum
Options:holdfallrise
Option 2number[]
intervalenum
Options:weeklymonthlyquarterlyyearly
measureenum

Which metric to compute. Every field-backed measure is sentinel-guarded: the source encodes unknown values as an out-of-range fill, so values outside the measure's plausible range are dropped before it is aggregated. Ranges: volume 0–100,000,000; avgRate 0–25; avgLoanAmount 0–100,000,000; avgCreditScore 300–850; avgLTV 0–999; avgDTI 0–999; avgIncome 0–100,000,000; avgAppraisedValue 0–100,000,000; avgPurchasePrice 0–100,000,000; avgDtiFront 0–999; avgCombinedLtv 0–999; avgLoanTerm 0–1,200; originatedVolume 0–100,000,000; originatedAvgDti 0–100. units and originatedUnits are document counts and are not guarded. Each response reports how many documents its guard excluded, so a mean taken over 98% of the data can be told apart from one taken over 60%. NOTE on population: units and volume cover loan APPLICATIONS of every outcome — denials, withdrawals and secondary-market purchases included — and so does avgDTI, while originatedUnits, originatedVolume and originatedAvgDti cover originations only.

Options:volumeunitsavgRateavgLoanAmountavgCreditScoreavgLTVavgDTIavgIncomeavgAppraisedValueavgPurchasePriceavgDtiFrontavgCombinedLtvavgLoanTermoriginatedUnitsoriginatedVolumeoriginatedAvgDti
periodenum

Date window for loans / sales / market endpoints. Accepts every Period value plus rolling windows: last30Days / last60Days / last90Days (today minus 30 / 60 / 90 days through today), previousMonth (the last complete calendar month) and currentMonth (the 1st of this month through today). All windows are resolved in UTC with inclusive calendar-date bounds. Rolling windows are only accepted by the loans, sales and market endpoints (list, count, breakdowns, analytics summary / time-series / chart); originators / companies / branches / agents / offices endpoints return 400 for them.

Options:2017201820192020202120222023202420252026last3Monthslast6Monthslast12Monthslast14Monthslast16Monthslast18Monthslast24MonthsyearToDateallTimelast30Dayslast60Dayslast90DayspreviousMonthcurrentMonth
segmentenum
Options:statecountymetroziploanPurposeloanTypepropertyTypeoccupancyTypeamortizationTypechannelborrowerGenerationfirstTimeHomebuyerveteranIndicatorhmdaActionTakenselfEmployedcurrentHomeOwnerlenderTypelenderVolumeClass

Responses

200objectTime series with previous-period comparison. Each bucket carries `volume`, `units`, and `measureValue` for the requested `measure`. With `forecast` in the request, a `forecast` block is appended.
Show attributes
completenessobject

Data-completeness watermark for this response. Present only when it could be measured; absence means it was not measured, NOT that the data is complete.

Show child attributes
throughdaterequired

The last calendar date (YYYY-MM-DD) this query's matching records actually reach. Records arrive after the events they describe, so a period ending today is normally backed by data ending days or weeks earlier, and any bucket extending past this date is built from a partial period. Measured from THIS query's own matched set, not a global figure: the delay varies by geography and moves over time, so two requests with different filters can legitimately report different dates.

currentobject[]required
Show child attributes
completeboolean

Whether this bucket's whole period is backed by data. false means the bucket extends past completeness.through, so it is built from a partial period and MUST NOT be compared against its neighbours or the same bucket a year earlier. Absent whenever completeness itself is absent; the two are emitted together or not at all.

datestringrequired
excludednumber

How many of this bucket's documents the requested measure's sentinel guard excluded — documents carrying the field whose value is an out-of-range fill. Compare against units to see the share the value was computed over. Present per BUCKET because exclusion is not uniform over time: one period can be almost entirely fill values while its neighbors are clean, and a single response-level total would hide exactly that. Absent for units, which is a document count and cannot be guarded.

measureValuenumber | nullrequired

This bucket's value for the requested measure (volume when none was supplied). Null when the bucket has no in-bounds document for the measure's field — sentinel-filtered rows do not contribute, so an empty bucket reports null rather than 0.

segmentsobject[]
Show child attributes
labelstringrequired
measureValuenumber | nullrequired

This segment's value for the requested measure. Null when the segment has no in-bounds document for the measure's field.

unattributedenum

Present and true on at most one segment PER DATE BUCKET, which is not a real category: it collects the documents that bucket could not attribute to any value of the requested segment, and its label ("(unknown)") is prose, not an identifier. Filter on THIS field, never on the label — a consumer joining a segment label to a real code must drop it. It is always the LAST entry of its bucket's segments, appended after ranking rather than placed by value, so it is the one segment that does not obey the ordering measure describes. It exists so a period's segments account for the same documents that period's own units counts: a document whose segment field holds no indexed term is absent from a terms breakdown entirely rather than forming a small segment, so without it a stacked series silently omits part of every bar. That reconciliation is exact for units; on an average it is not, because segments under the five-document floor are dropped and a segment field with more than 200 distinct values still truncates — neither loss is collected here. Reported per bucket rather than once per response because what cannot be attributed is not uniform over time. Absent when there is nothing unattributed, never false and never a zero-valued segment.

Options:true
unitsnumberrequired
volumenumberrequired
unitsnumberrequired

Number of loans

volumenumberrequired

Total loan volume in dollars

forecastobject

Present only when the request carried forecast. History above is unchanged; the forecast starts the month after forecast.asOf.

Show child attributes
asOfstringrequired

First day of the last month of history the model saw (yyyy-MM-dd). The forecast begins the following month.

cachedbooleanrequired

True when served from cache (same request, same data version).

confidenceenumrequired

Support tier: high ≥ 100/month, medium ≥ 20/month, low below. Below 20/month the series is mostly noise and the band is wide; treat low as a shape, not a number.

Options:highmediumlow
horizonintegerrequired
intervalenumrequired
Options:monthly
modelstringrequired

Model id that produced the quantiles.

pointsobject[]required
Show child attributes
datestringrequired

First day of the forecast month, yyyy-MM-dd.

p10numberrequired
p50numberrequired

Median forecast.

p90numberrequired
scenarioobject | nullrequired

The resolved covariate path the forecast conditioned on, one value per horizon month. null when the rate series was unavailable and the forecast ran without it.

Show child attributes
rate30ynumber[]required
segmentsobject[]

Per-segment forecasts when the request carried segment, one per label (top 12 by history total). Independent forecasts — they are not reconciled to sum to the total.

Show child attributes
confidenceenumrequired

Support tier: high ≥ 100/month, medium ≥ 20/month, low below. Below 20/month the series is mostly noise and the band is wide; treat low as a shape, not a number.

Options:highmediumlow
labelstringrequired

Segment label, never blank. Documents the dimension could not bucket are reported on the time-series history as its (unknown) segment; that disclosure is not a category and is not forecast.

pointsobject[]required
supportnumberrequired

Mean monthly value of the forecast target over the last 12 months of history the model saw. The number behind confidence.

supportnumberrequired

Mean monthly value of the forecast target over the last 12 months of history the model saw. The number behind confidence.

trimmedMonthsintegerrequired

Trailing months dropped from history before forecasting because they are still filling in (ingest lag on application months; closing lag on originated measures).

measurestringrequired

Echo of the measure measureValue reports, so a caller never has to infer which metric it is plotting.

previousobject[] | nullrequired
Show child attributes
completeboolean

Whether this bucket's whole period is backed by data. false means the bucket extends past completeness.through, so it is built from a partial period and MUST NOT be compared against its neighbours or the same bucket a year earlier. Absent whenever completeness itself is absent; the two are emitted together or not at all.

datestringrequired
excludednumber

How many of this bucket's documents the requested measure's sentinel guard excluded — documents carrying the field whose value is an out-of-range fill. Compare against units to see the share the value was computed over. Present per BUCKET because exclusion is not uniform over time: one period can be almost entirely fill values while its neighbors are clean, and a single response-level total would hide exactly that. Absent for units, which is a document count and cannot be guarded.

measureValuenumber | nullrequired

This bucket's value for the requested measure (volume when none was supplied). Null when the bucket has no in-bounds document for the measure's field — sentinel-filtered rows do not contribute, so an empty bucket reports null rather than 0.

segmentsobject[]
Show child attributes
labelstringrequired
measureValuenumber | nullrequired

This segment's value for the requested measure. Null when the segment has no in-bounds document for the measure's field.

unattributedenum

Present and true on at most one segment PER DATE BUCKET, which is not a real category: it collects the documents that bucket could not attribute to any value of the requested segment, and its label ("(unknown)") is prose, not an identifier. Filter on THIS field, never on the label — a consumer joining a segment label to a real code must drop it. It is always the LAST entry of its bucket's segments, appended after ranking rather than placed by value, so it is the one segment that does not obey the ordering measure describes. It exists so a period's segments account for the same documents that period's own units counts: a document whose segment field holds no indexed term is absent from a terms breakdown entirely rather than forming a small segment, so without it a stacked series silently omits part of every bar. That reconciliation is exact for units; on an average it is not, because segments under the five-document floor are dropped and a segment field with more than 200 distinct values still truncates — neither loss is collected here. Reported per bucket rather than once per response because what cannot be attributed is not uniform over time. Absent when there is nothing unattributed, never false and never a zero-valued segment.

Options:true
unitsnumberrequired
volumenumberrequired
unitsnumberrequired

Number of loans

volumenumberrequired

Total loan volume in dollars

400objectValidation error. With `forecast`, `code` says which rule tripped: non-monthly interval, an average measure, or under 24 months of history.
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
503objectOnly with `forecast`: the forecast service is unreachable or not configured for this stage. The history itself is fine — retry without `forecast` for an immediate answer. Also returned as `SearchUnavailable` (`error`: `search_timeout` / `search_overloaded`) when the search ran out of time or the cluster shed it.