{"components":{"parameters":{},"schemas":{"AccountServiceUnavailable":{"properties":{"error":{"type":"string"}},"required":["error"],"type":"object"},"AddWatchedAgentRequest":{"properties":{"agentId":{"description":"Agent id to watch.","minLength":1,"type":"string"}},"required":["agentId"],"type":"object"},"AddWatchedAreaRequest":{"properties":{"lat":{"description":"Center latitude (point + radius).","maximum":90,"minimum":-90,"type":"number"},"lon":{"description":"Center longitude.","maximum":180,"minimum":-180,"type":"number"},"maxLat":{"description":"Box north edge.","maximum":90,"minimum":-90,"type":"number"},"maxLon":{"description":"Box east edge.","maximum":180,"minimum":-180,"type":"number"},"minLat":{"description":"Box south edge.","maximum":90,"minimum":-90,"type":"number"},"minLon":{"description":"Box west edge.","maximum":180,"minimum":-180,"type":"number"},"radius":{"description":"Radius around the center point.","example":10,"exclusiveMinimum":true,"minimum":0,"type":"number"},"state":{"description":"2-letter state. Ignored for zip + geo areas.","example":"CA","type":"string"},"type":{"description":"Named area (city/county/zip) or geo area (bbox = bounding box, radius = point + radius).","enum":["city","county","zip","bbox","radius"],"type":"string"},"unit":{"description":"Radius unit (default mi).","enum":["mi","km","m"],"example":"mi","type":"string"},"value":{"description":"City / county name, or 5-digit zip. Required for named areas.","example":"Los Angeles","type":"string"}},"required":["type"],"type":"object"},"AddWatchedDocumentRequest":{"properties":{"documentId":{"description":"The document id (mm_property_id / mm_loan_id / mm_sale_id).","minLength":1,"type":"string"},"documentType":{"description":"The kind of document to watch.","enum":["sale","property","loan"],"example":"property","type":"string"},"rules":{"description":"One or more rules; each fires as one alert.","items":{"properties":{"match":{"description":"How predicates combine: all (AND, default) or any (OR).","enum":["all","any"],"example":"all","type":"string"},"predicates":{"description":"One or more conditions; combined per match.","items":{"properties":{"field":{"description":"Catalog field alias (e.g. avm, current_ltv, loan_type).","example":"current_ltv","type":"string"},"op":{"description":"Comparison / change / status / guard operator.","enum":["gt","gte","lt","lte","eq","between","pct_change_gte","abs_change_gte","changed","changed_to"],"example":"lte","type":"string"},"stringValue":{"description":"Target keyword for changed_to / eq guard.","type":"string"},"value":{"description":"Threshold, or change amount (percent for pct_change_gte).","example":0.8,"type":"number"},"value2":{"description":"Upper bound for between.","type":"number"}},"required":["field","op"],"type":"object"},"minItems":1,"type":"array"}},"required":["predicates"],"type":"object"},"minItems":1,"type":"array"}},"required":["documentType","documentId","rules"],"type":"object"},"AdminAlertConditionsResponse":{"properties":{"data":{"properties":{"conditions":{"$ref":"#/components/schemas/AlertConditions"},"email":{"type":"string"},"emailEnabled":{"$ref":"#/components/schemas/AlertEnabled"},"enabled":{"$ref":"#/components/schemas/AlertEnabled"},"name":{"type":"string"},"nmlsId":{"type":"string"},"orgId":{"type":"string"},"updatedAt":{"type":"string"},"userId":{"type":"string"}},"required":["userId","orgId","nmlsId","email","name","enabled","emailEnabled","conditions","updatedAt"],"type":"object"}},"required":["data"],"type":"object"},"AdminAlertDigestItem":{"allOf":[{"$ref":"#/components/schemas/AlertDigestItem"},{"properties":{"correlationId":{"description":"The detector run that produced this digest (trace to /runs).","type":"string"},"userId":{"type":"string"}},"required":["userId"],"type":"object"}]},"AdminAlertDigestResponse":{"properties":{"cursor":{"type":"string"},"items":{"items":{"$ref":"#/components/schemas/AdminAlertDigestItem"},"type":"array"}},"required":["items"],"type":"object"},"AdminAlertLogItem":{"allOf":[{"$ref":"#/components/schemas/AlertLogItem"},{"properties":{"correlationId":{"description":"The detector run that produced this alert (trace to /runs).","type":"string"},"userId":{"type":"string"}},"required":["userId"],"type":"object"}]},"AdminAlertLogResponse":{"properties":{"cursor":{"type":"string"},"items":{"items":{"$ref":"#/components/schemas/AdminAlertLogItem"},"type":"array"}},"required":["items"],"type":"object"},"AdminAlertRawResponse":{"properties":{"data":{"additionalProperties":{"nullable":true},"type":"object"}},"required":["data"],"type":"object"},"AdminAlertRunRecord":{"properties":{"correlationId":{"type":"string"},"dryRun":{"type":"boolean"},"durationMs":{"type":"integer"},"finishedAt":{"type":"string"},"id":{"type":"string"},"perDetector":{"items":{"properties":{"deduped":{"type":"integer"},"matched":{"type":"integer"},"published":{"type":"integer"},"scanned":{"type":"integer"},"type":{"enum":["area_new_listing","watched_agent_pending","borrower_listed","epo_risk","agent_sale_closed","rate_term_refi_area","watched_sale","watched_property","watched_loan"],"type":"string"},"written":{"type":"integer"}},"required":["type","scanned","matched","deduped","written","published"],"type":"object"},"type":"array"},"startedAt":{"type":"string"},"totals":{"properties":{"matched":{"type":"integer"},"published":{"type":"integer"},"scanned":{"type":"integer"},"written":{"type":"integer"}},"required":["scanned","matched","written","published"],"type":"object"}},"required":["id","correlationId","startedAt","finishedAt","durationMs","dryRun","perDetector","totals"],"type":"object"},"AdminAlertRunResponse":{"properties":{"data":{"$ref":"#/components/schemas/AdminAlertRunRecord"}},"required":["data"],"type":"object"},"AdminAlertRunsResponse":{"properties":{"cursor":{"type":"string"},"items":{"items":{"$ref":"#/components/schemas/AdminAlertRunRecord"},"type":"array"}},"required":["items"],"type":"object"},"AdminBulkJob":{"properties":{"bytes":{"type":"number"},"chargedCount":{"type":"number"},"completedAt":{"type":"string"},"creditLedgerId":{"nullable":true,"type":"string"},"creditsCharged":{"type":"number"},"entityType":{"type":"string"},"error":{"type":"string"},"failed":{"type":"number"},"format":{"type":"string"},"fromCache":{"type":"number"},"jobId":{"type":"string"},"jobType":{"enum":["enrichment","bulk-delivery","crm-production-enrich","crm-import"],"type":"string"},"orgId":{"type":"string"},"processed":{"type":"number"},"startedAt":{"type":"string"},"status":{"enum":["queued","running","completed","failed"],"type":"string"},"succeeded":{"type":"number"},"total":{"type":"number"},"userId":{"type":"string"}},"required":["jobId","orgId","userId","jobType","status","total","succeeded","failed","fromCache","chargedCount","creditsCharged","creditLedgerId"],"type":"object"},"AdminBulkJobResponse":{"properties":{"job":{"$ref":"#/components/schemas/AdminBulkJob"},"resultsUrl":{"nullable":true,"type":"string"}},"required":["job","resultsUrl"],"type":"object"},"AdminPushAlertRequest":{"properties":{"dedupeKey":{"description":"Dedup key; generated server-side when omitted.","type":"string"},"orgId":{"description":"Workspace id so the push also lands in the org feed.","type":"string"},"payload":{"additionalProperties":{"nullable":true},"description":"Human description + optional link + fields.","properties":{"description":{"type":"string"},"url":{"type":"string"}},"required":["description"],"type":"object"},"type":{"description":"One of the six alert types.","enum":["area_new_listing","watched_agent_pending","borrower_listed","epo_risk","agent_sale_closed","rate_term_refi_area","watched_sale","watched_property","watched_loan"],"type":"string"}},"required":["type","payload"],"type":"object"},"AdminPushAlertResponse":{"properties":{"data":{"properties":{"dedupeKey":{"type":"string"},"written":{"type":"boolean"}},"required":["written","dedupeKey"],"type":"object"}},"required":["data"],"type":"object"},"AdminUpdateAlertConditionsRequest":{"properties":{"conditions":{"$ref":"#/components/schemas/AlertConditions"},"email":{"type":"string"},"emailEnabled":{"properties":{"agent_sale_closed":{"type":"boolean"},"area_new_listing":{"type":"boolean"},"borrower_listed":{"type":"boolean"},"epo_risk":{"type":"boolean"},"rate_term_refi_area":{"type":"boolean"},"watched_agent_pending":{"type":"boolean"},"watched_loan":{"type":"boolean"},"watched_property":{"type":"boolean"},"watched_sale":{"type":"boolean"}},"type":"object"},"enabled":{"properties":{"agent_sale_closed":{"type":"boolean"},"area_new_listing":{"type":"boolean"},"borrower_listed":{"type":"boolean"},"epo_risk":{"type":"boolean"},"rate_term_refi_area":{"type":"boolean"},"watched_agent_pending":{"type":"boolean"},"watched_loan":{"type":"boolean"},"watched_property":{"type":"boolean"},"watched_sale":{"type":"boolean"}},"type":"object"},"name":{"type":"string"},"nmlsId":{"type":"string"},"orgId":{"description":"Workspace id stamped on the config (admin supplies it). Required — alerts are org-scoped, so a config can't exist without a workspace.","minLength":1,"type":"string"}},"required":["orgId"],"type":"object"},"AgentChartMeasure":{"default":"units","description":"Which metric each bar reports — and, with one exception, NOT what the bars are ranked by. Ranking is by transaction count unless you explicitly pass `volume`, which ranks by dollars instead. Defaults to `units`, so \"top originators\" means the busiest rather than the biggest. The average measures deliberately rank by count too: ordering a high-cardinality slice by its own mean returns whichever one-transaction buckets happened to score highest, so \"top zips by average rate\" would mean \"zips with one weird loan\" — ranked by count it means \"the busiest zips, with their rates\". Every bucket publishes its own `count`, so the sample size behind a value is never implicit.","enum":["volume","units","avgSalePrice"],"type":"string"},"AgentChartRequest":{"additionalProperties":false,"properties":{"id":{"type":"string"},"ids":{"items":{"type":"string"},"type":"array"},"measure":{"$ref":"#/components/schemas/AgentChartMeasure"},"period":{"$ref":"#/components/schemas/Period"},"slice":{"$ref":"#/components/schemas/AgentChartSlice"}},"required":["slice"],"type":"object"},"AgentChartSlice":{"enum":["city","county","state","zip"],"type":"string"},"AgentCountyFilterValue":{"anyOf":[{"pattern":"^\\d{5}$/u","type":"string"},{"description":"Match any of several counties","items":{"pattern":"^\\d{5}$/u","type":"string"},"type":"array"},{"nullable":true}],"description":"Production county, keyed by 5-digit county FIPS code (e.g. `06037` = Los Angeles, CA; `04013` = Maricopa, AZ). Matches agents who closed transactions in this county — NOT their office or listed address, which carry no county data at all. A county NAME is REJECTED with a 400 naming the expected format; resolve the name to its FIPS code first (via instantSearch), or use `city`/`state`, which do accept names. Location dimensions AND with each other, so `county` + `state` returns only agents matching both; what sets `county` apart from `city`/`state`/`zip` is its source — those are satisfied by an office address OR a production market, `county` by production alone."},"AgentDetail":{"allOf":[{"$ref":"#/components/schemas/AgentSummary"},{"properties":{"licenses":{"items":{"$ref":"#/components/schemas/AgentLicense"},"nullable":true,"type":"array"},"linkedProfileCount":{"description":"Total consolidated records for this agent, before the 20-entry cap applied to `linkedProfiles`.","nullable":true,"type":"number"},"linkedProfiles":{"description":"Additional records consolidated into this agent — the SAME person as captured by different data sources, not teammates or a team roster. Useful for the alternate contact details and the transaction window each record carries. Ordered by transaction count, highest first, and capped at 20 entries; `linkedProfileCount` is the uncapped total.","items":{"$ref":"#/components/schemas/AgentLinkedProfile"},"nullable":true,"type":"array"},"scored":{"nullable":true}},"type":"object"}]},"AgentDetailResponse":{"properties":{"data":{"$ref":"#/components/schemas/AgentDetail"}},"required":["data"],"type":"object"},"AgentField":{"enum":["office","city","state","zip","volume","units","avgSalePrice","buyerVolume","buyerUnits","sellerVolume","sellerUnits","dualVolume","dualUnits","name","firstName","lastName","email","producersOnly"],"type":"string"},"AgentFootprintFilter":{"additionalProperties":false,"properties":{"avgLoanAmount":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"Mean loan size financed by this lender on the agent's deals."}]},"dimension":{"description":"Which footprint to address. Only `lender` is available for agents — it is inferred from a `lender` key, so you rarely pass this. Name it to ask the ANY-lender question (`{dimension:'lender', volume:{gte:10000000}}` = 'some single lender financed $10M of their sales'). A geographic dimension is a 400 naming the per-agent markets endpoint, which live-aggregates that answer.","enum":["zip","city","county","state","lender"],"type":"string"},"lender":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"description":"Financing lender, as an id from `listLenders` or `instantSearch`. Lender names are stored in a normalized dictionary form, so a typed name does not match — resolve it first. Several values UNION."},"not":{"description":"Invert the whole entry: match agents with NO lender relationship matching it.","type":"boolean"},"product":{"$ref":"#/components/schemas/FootprintProductFilter"},"units":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"Count of the agent's transactions financed by this lender during the selected period."}]},"volume":{"$ref":"#/components/schemas/FootprintRange"}},"type":"object"},"AgentLicense":{"properties":{"expirationDate":{"nullable":true,"type":"string"},"number":{"nullable":true,"type":"string"},"state":{"nullable":true,"type":"string"},"type":{"nullable":true,"type":"string"}},"type":"object"},"AgentLicenseFilterValue":{"anyOf":[{"type":"string"},{"description":"Match any of several licenses","items":{"type":"string"},"type":"array"},{"nullable":true}],"description":"Real-estate license number, matched EXACTLY. Case and surrounding whitespace are normalized, so `EB00084246`, `eb00084246` and `\" eb00084246 \"` all behave identically — paste straight from a spreadsheet or PDF. Punctuation is NOT normalized: `52219-90` and `5221990` are treated as different licenses, because separator-insensitive matching merges distinct agents. Matches against EVERY license on the agent's record, not just the one shown as `licenseNumber` on the response row — an agent licensed in two states is found by either. Fuzzy `{match}` is rejected with a 400: a near-miss on a license number is a different person, not a typo to forgive. Present on roughly 49% of agents; the rest carry no license at all and cannot be matched by this filter."},"AgentLinkedProfile":{"properties":{"email":{"nullable":true,"type":"string"},"firstTransactionDate":{"nullable":true,"type":"string"},"lastTransactionDate":{"nullable":true,"type":"string"},"name":{"nullable":true,"type":"string"},"officePhone":{"nullable":true,"type":"string"},"phone":{"nullable":true,"type":"string"},"transactions":{"description":"Transactions observed on this record.","nullable":true,"type":"number"}},"type":"object"},"AgentListRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"avgMortgagedLoanAmount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean loan size across the agent's financed deals — the price band their buyers actually borrow in."}]},"avgSalePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"buyerUnits":{"$ref":"#/components/schemas/NumericFilterValue"},"buyerVolume":{"$ref":"#/components/schemas/NumericFilterValue"},"city":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"City — matches across ALL of an agent's location signals (listed city, office address, AND transaction/production markets), OR'd together. An agent can match this city while their row's displayed `city`/`state` (their primary market) is elsewhere."}]},"county":{"$ref":"#/components/schemas/AgentCountyFilterValue"},"dualUnits":{"$ref":"#/components/schemas/NumericFilterValue"},"dualVolume":{"$ref":"#/components/schemas/NumericFilterValue"},"email":{"$ref":"#/components/schemas/TextFilterValue"},"firstName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"Deprecated: the fuzzy name filters can return the wrong agent. Resolve the agent via instantSearch (POST /v1/instant-search) and pass the returned `id` to the `id` filter for an exact match."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"id":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exact agent id — the `id` returned by instantSearch (same value as `modelMatchId`). Resolves the agent by its canonical ModelMatch id or any since-merged legacy id. Preferred over the fuzzy `name` filter."}]},"lastName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"Deprecated: the fuzzy name filters can return the wrong agent. Resolve the agent via instantSearch (POST /v1/instant-search) and pass the returned `id` to the `id` filter for an exact match."}]},"licenseNumber":{"$ref":"#/components/schemas/AgentLicenseFilterValue"},"mode":{"enum":["and","or"],"type":"string"},"modelMatchId":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `id` — the agent's ModelMatch id. Exact match (canonical or since-merged legacy id)."}]},"mortgagedBuyerUnits":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Count of the agent's buyer-side deals that were financed — the sharpest 'how many mortgage introductions can this agent make' number on the record."}]},"mortgagedBuyerVolume":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Dollar volume of the agent's BUYER-side deals that were financed. Measured independently of `buyerVolume`, not carved out of it, so it is not guaranteed to be smaller."}]},"mortgagedDualUnits":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Count of the agent's dual-agency deals that were financed."}]},"mortgagedDualVolume":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Dollar volume of the agent's dual-agency deals that were financed."}]},"mortgagedSellerUnits":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Count of the agent's seller-side (listing) deals whose buyer financed."}]},"mortgagedSellerVolume":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Dollar volume of the agent's SELLER-side (listing) deals whose buyer financed."}]},"name":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"Deprecated: the fuzzy name filters can return the wrong agent. Resolve the agent via instantSearch (POST /v1/instant-search) and pass the returned `id` to the `id` filter for an exact match."}]},"office":{"$ref":"#/components/schemas/TextFilterValue"},"percentUnitsMortgaged":{"anyOf":[{"type":"number"},{"description":"Match any value","items":{"type":"number"},"type":"array"},{"description":"Numeric range. Excludes null/missing-field docs by default; add `includeNulls: true` to keep them.","properties":{"gt":{"type":"number"},"gte":{"type":"number"},"includeNulls":{"description":"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.","type":"boolean"},"lt":{"type":"number"},"lte":{"type":"number"}},"type":"object"},{"nullable":true}],"description":"Share of the agent's TRANSACTIONS that were financed with a mortgage, as a 0–100 percent — the by-count twin of `percentVolumeMortgaged`, and the better one when deal size varies wildly. Same 0–100 clamp."},"percentVolumeMortgaged":{"anyOf":[{"type":"number"},{"description":"Match any value","items":{"type":"number"},"type":"array"},{"description":"Numeric range. Excludes null/missing-field docs by default; add `includeNulls: true` to keep them.","properties":{"gt":{"type":"number"},"gte":{"type":"number"},"includeNulls":{"description":"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.","type":"boolean"},"lt":{"type":"number"},"lte":{"type":"number"}},"type":"object"},{"nullable":true}],"description":"Share of the agent's sale volume that was financed with a mortgage, as a 0–100 percent. `{gte:80}` = 'almost everything they sell is financed' (211,079 agents over the last 12 months); `{lte:20}` finds cash-heavy books. Values are clamped at 100 — a small number of records carry a computed percent above 100, and they are treated as fully financed rather than silently kept or dropped. Bounds outside 0–100 are rejected."},"producersOnly":{"$ref":"#/components/schemas/BooleanFilterValue"},"sellerUnits":{"$ref":"#/components/schemas/NumericFilterValue"},"sellerVolume":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"State — matches across ALL of an agent's location signals (listed state, office address, AND transaction/production markets), OR'd together. So an agent whose office is in another state still matches if they closed transactions here."}]},"totalCompaniesWorkedWith":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"How many distinct mortgage COMPANIES financed this agent's deals in the selected period."}]},"totalLendersWorkedWith":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"How many distinct LENDERS financed this agent's deals in the selected period."}]},"totalOriginatorsWorkedWith":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"How many DISTINCT loan officers financed this agent's deals in the selected period. `{lte:1}` finds agents with a single LO relationship — the displacement target; `{gte:5}` finds agents who spread their referrals around. Same number shown on the response row."}]},"units":{"$ref":"#/components/schemas/NumericFilterValue"},"volume":{"$ref":"#/components/schemas/NumericFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"ZIP — matches across ALL of an agent's location signals, OR'd together: an office postal code, OR a ZIP they actually closed transactions in (their production market). So an agent whose office is elsewhere still matches if they sold here, and the `zip` shown on their row (their primary market) can differ from the one you searched. Supply the 5-digit form; ZIP+4 input is reduced to its 5-digit prefix. Canonical key; `zipCode` is an accepted alias."}]},"zipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zip` — identical behavior. Kept so the `zipCode` spelling used by loans/sales works here too."}]}},"type":"object"},"footprint":{"anyOf":[{"$ref":"#/components/schemas/AgentFootprintFilter"},{"items":{"$ref":"#/components/schemas/AgentFootprintFilter"},"type":"array"}],"description":"Scoped lender filter(s). Each entry names ONE financing relationship and the metric bounds that must hold INSIDE it — `{lender:'<id>', volume:{gte:10000000}}` means '$10M of their sales were financed by that lender', not '$10M of sales and one deal with them'. Several entries AND together. Geographic market filters are not available here: use `POST /agents/{id}/markets` (live-aggregated) for an agent's geography."},"lenderFilters":{"items":{"$ref":"#/components/schemas/LenderFilterEntry"},"type":"array"},"lenderMatchMode":{"$ref":"#/components/schemas/LenderMatchMode"},"pagination":{"$ref":"#/components/schemas/Pagination"},"period":{"$ref":"#/components/schemas/Period"},"sort":{"items":{"properties":{"field":{"$ref":"#/components/schemas/AgentField"},"order":{"$ref":"#/components/schemas/SortOrder"}},"required":["field"],"type":"object"},"type":"array"}},"type":"object"},"AgentListResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/AgentSummary"},"type":"array"},"locationNormalizations":{"description":"How each location filter value resolved. Present when a `city`/`county`/`state`/`zip` filter was supplied.","items":{"$ref":"#/components/schemas/LocationNormalization"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"AgentMarket":{"properties":{"avgSalePrice":{"description":"`volume ÷ units` — the mean priced sale in this market.","nullable":true,"type":"number"},"shareOfScope":{"description":"This market's share of the agent's volume ACROSS THE SCOPE REQUESTED, 0–100. It sums to 100 over the whole scope, so a page truncated by `limit` sums to less than 100 by exactly the share left out — the shares do not re-normalize to the page, because a number that moved every time you changed the page size would not be a share of anything stable. It is NOT this agent's share of the market itself, and it is not comparable across agents.","nullable":true,"type":"number"},"transactions":{"description":"Transaction records matched in this market. NOT every one of them carries a price — compare with `units`.","type":"number"},"units":{"description":"Priced transaction records — the ones that contributed to `volume`, and the divisor behind `avgSalePrice`. Typically about half of `transactions`.","nullable":true,"type":"number"},"volume":{"description":"Total sale price across the priced records.","nullable":true,"type":"number"},"zipCode":{"description":"The ZIP code this market is keyed by.","nullable":true,"type":"string"}},"required":["zipCode","transactions","units","volume","avgSalePrice","shareOfScope"],"type":"object"},"AgentMarketsCommunityLending":{"description":"The Community Lending mix of this footprint: the neighborhood characteristics of where the production landed, as percentages on a 0-100 scale. Null when nothing in scope resolved to a neighborhood — an absent block, never a row of zeroes, because 'no data' and '0%' are different answers. Read `basis` before comparing two responses. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"properties":{"affordableHousingTractPct":{"description":"Share of production, 0-100, in neighborhoods carrying an affordable-housing designation. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"basis":{"description":"Which measurement produced this block, and they are NOT the same number. `entityRollup` is the neighborhood mix of the entity's own production over the whole period — the default. `marketsInScope` is the neighborhood profile of the markets the request selected, weighted by the entity's production in each, and is what any ZIP, date or filter scope returns, because a whole-period rollup cannot be re-cut to a narrower question.","enum":["entityRollup","marketsInScope"],"type":"string"},"coveredProductionPct":{"description":"`marketsInScope` only — what share of the weighted production, 0-100, sits in a market that resolved to neighborhood data. Below 100 means the mix describes part of the footprint, not all of it.","nullable":true,"type":"number"},"difficultDevelopmentAreaPct":{"description":"Share of production, 0-100, in designated difficult development areas. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"distressedTractPct":{"description":"Share of production, 0-100, in distressed or underserved nonmetropolitan middle-income neighborhoods. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"floodHazardTractPct":{"description":"Share of production, 0-100, in neighborhoods inside a special flood hazard area. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"incomeLevelMix":{"description":"`marketsInScope` only — the full relative-income distribution of the neighborhoods, 0-100, summing to about 100. Null on `entityRollup`, which stores the predominant band but no distribution; publishing one derived from a single label would be a histogram nobody measured. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"properties":{"low":{"nullable":true,"type":"number"},"middle":{"nullable":true,"type":"number"},"moderate":{"nullable":true,"type":"number"},"upper":{"nullable":true,"type":"number"}},"required":["low","moderate","middle","upper"],"type":"object"},"loansWithCommunityData":{"description":"`entityRollup` only — how many of the entity's transactions in the period resolved to a neighborhood. This is the denominator every share below is a share OF, so read it first: a 100% share over three transactions is not a footprint.","nullable":true,"type":"number"},"lowModIncomeTractPct":{"description":"Share of production, 0-100, in low- or moderate-income neighborhoods. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"majorityMinorityTractPct":{"description":"Share of production, 0-100, in majority-minority neighborhoods. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"marketsInScope":{"description":"`marketsInScope` only — ZIP markets the mix considered, including any that carried no neighborhood data.","nullable":true,"type":"number"},"marketsWithCommunityData":{"description":"`marketsInScope` only — ZIP markets that resolved to neighborhood data.","nullable":true,"type":"number"},"opportunityZonePct":{"description":"Share of production, 0-100, in designated Opportunity Zones. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"predominantIncomeLevel":{"description":"The most common relative-income classification of the neighborhoods, on the standard four-band scale. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","enum":["low","moderate","middle","upper",null],"nullable":true,"type":"string"},"ruralTractPct":{"description":"Share of production, 0-100, in neighborhoods classified rural. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"usdaEligibleTractPct":{"description":"Share of production, 0-100, in neighborhoods eligible for USDA rural housing programs. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"}},"required":["basis","loansWithCommunityData","marketsWithCommunityData","marketsInScope","coveredProductionPct","predominantIncomeLevel","incomeLevelMix","lowModIncomeTractPct","majorityMinorityTractPct","ruralTractPct","opportunityZonePct","affordableHousingTractPct","distressedTractPct","usdaEligibleTractPct","floodHazardTractPct","difficultDevelopmentAreaPct"],"type":"object"},"AgentMarketsDateRange":{"additionalProperties":false,"description":"Narrow the footprint to transactions inside this window. Omit for the agent's whole recorded history.","properties":{"from":{"description":"Inclusive lower bound on the transaction date.","example":"2024-01-01","pattern":"^\\d{4}(-\\d{2}(-\\d{2})?)?$/u","type":"string"},"to":{"description":"Inclusive upper bound on the transaction date.","example":"2025-12-31","pattern":"^\\d{4}(-\\d{2}(-\\d{2})?)?$/u","type":"string"}},"type":"object"},"AgentMarketsReach":{"properties":{"presentInScope":{"description":"Whether this agent is present in the requested ZIP scope at all — by office location OR by any transaction on record. Null when no scope was requested. `true` with an empty `markets` array means the agent works that market but has no priced transaction there in the window, which is a different answer from `false`.","nullable":true,"type":"boolean"},"transactedInScope":{"description":"Whether the scope produced any market with recorded transactions. Null when no scope was requested.","nullable":true,"type":"boolean"},"zipCodesRequested":{"description":"The normalized ZIP scope actually applied, or null when the caller asked for the whole footprint.","items":{"type":"string"},"nullable":true,"type":"array"}},"required":["zipCodesRequested","presentInScope","transactedInScope"],"type":"object"},"AgentMarketsRequest":{"additionalProperties":false,"properties":{"dateRange":{"$ref":"#/components/schemas/AgentMarketsDateRange"},"limit":{"description":"How many markets to return, ranked by volume descending (default 50). The summary is computed over the whole footprint BEFORE this truncation, so changing it never moves the totals or the average.","maximum":500,"minimum":1,"type":"integer"},"zipCodes":{"description":"Narrow the footprint to these ZIP codes. 1–5 digits; a value that is not a ZIP is a 400 naming it, never a silently narrower result. Leading zeros may be omitted (`1001` resolves to `01001`).","example":["77316","77578"],"items":{"type":"string"},"maxItems":200,"minItems":1,"type":"array"}},"type":"object"},"AgentMarketsResponse":{"properties":{"data":{"properties":{"agentId":{"description":"The canonical agent id these markets were computed for. May differ from the id sent if that id was a pre-merge one.","type":"string"},"basis":{"description":"This is a REACH view. An agent belongs to every market they touch, so agent counts across markets over-sum and cannot be turned into a market share. See `notes`.","enum":["reach"],"type":"string"},"markets":{"items":{"$ref":"#/components/schemas/AgentMarket"},"type":"array"},"notes":{"description":"Plain-language caveats that apply to every figure above.","items":{"type":"string"},"type":"array"},"reach":{"$ref":"#/components/schemas/AgentMarketsReach"},"source":{"$ref":"#/components/schemas/AgentMarketsSource"},"summary":{"$ref":"#/components/schemas/AgentMarketsSummary"}},"required":["agentId","basis","markets","summary","reach","source","notes"],"type":"object"}},"required":["data"],"type":"object"},"AgentMarketsSource":{"properties":{"mode":{"enum":["live"],"type":"string"},"reasons":{"description":"Why the figures were computed live from transaction records rather than read from a stored rollup.","items":{"type":"string"},"type":"array"}},"required":["mode","reasons"],"type":"object"},"AgentMarketsSummary":{"properties":{"avgSalePrice":{"description":"Volume-weighted mean priced sale across the footprint. Equal to `volume ÷ units`; NOT the average of the per-market averages, which drifts with market size.","nullable":true,"type":"number"},"communityLending":{"$ref":"#/components/schemas/AgentMarketsCommunityLending"},"marketCount":{"description":"How many placed markets contributed to this summary — the whole footprint inside the considered set, not the number of rows returned.","type":"number"},"shareOfBook":{"description":"Always null on this surface. A share of an agent's whole book would need a per-agent total to divide by, and the transaction records carry none — publishing a partial sum as a total is the error this field exists to refuse.","nullable":true},"transactions":{"type":"number"},"units":{"nullable":true,"type":"number"},"unresolved":{"$ref":"#/components/schemas/AgentMarketsUnresolved"},"volume":{"nullable":true,"type":"number"}},"required":["marketCount","transactions","units","volume","avgSalePrice","shareOfBook","unresolved","communityLending"],"type":"object"},"AgentMarketsUnresolved":{"description":"Transactions whose market could not be placed. Held OUT of the summary and every ranking, and reported here so the coverage is stated rather than hidden.","properties":{"transactions":{"type":"number"},"units":{"nullable":true,"type":"number"},"volume":{"nullable":true,"type":"number"}},"required":["transactions","units","volume"],"type":"object"},"AgentPropertiesResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/AgentPropertySummary"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"AgentPropertySummary":{"properties":{"address":{"nullable":true,"type":"string"},"city":{"nullable":true,"type":"string"},"date":{"nullable":true,"type":"string"},"id":{"type":"string"},"mmPropertyId":{"nullable":true,"type":"string"},"price":{"nullable":true,"type":"number"},"propertyType":{"nullable":true,"type":"string"},"state":{"nullable":true,"type":"string"},"zip":{"nullable":true,"type":"string"}},"required":["id"],"type":"object"},"AgentRelationRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/SaleFlatFilters"},"pagination":{"$ref":"#/components/schemas/Pagination"},"period":{"$ref":"#/components/schemas/Period"},"sort":{"items":{"properties":{"field":{"type":"string"},"order":{"$ref":"#/components/schemas/SortOrder"}},"required":["field"],"type":"object"},"type":"array"}},"type":"object"},"AgentSaleSummary":{"properties":{"address":{"nullable":true,"type":"string"},"city":{"nullable":true,"type":"string"},"date":{"nullable":true,"type":"string"},"id":{"type":"string"},"listAgentName":{"nullable":true,"type":"string"},"price":{"nullable":true,"type":"number"},"soldAgentName":{"nullable":true,"type":"string"},"state":{"nullable":true,"type":"string"},"txType":{"description":"Property type for the transacted property (e.g. `Residential`, `Condominium`) — the same value `/v1/sales` returns as `propertyType`. Named `txType` for backwards compatibility. Present on roughly 19% of sales; the rest carry no MLS listing type and read `null`.","nullable":true,"type":"string"},"zip":{"nullable":true,"type":"string"}},"required":["id"],"type":"object"},"AgentSalesResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/AgentSaleSummary"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"AgentSummary":{"properties":{"avgSoldPrice":{"nullable":true,"type":"number"},"buyerUnits":{"nullable":true,"type":"number"},"buyerVolume":{"nullable":true,"type":"number"},"city":{"nullable":true,"type":"string"},"dualUnits":{"nullable":true,"type":"number"},"dualVolume":{"nullable":true,"type":"number"},"email":{"nullable":true,"type":"string"},"firstName":{"nullable":true,"type":"string"},"fullName":{"nullable":true,"type":"string"},"id":{"description":"Document ID","type":"string"},"lastName":{"nullable":true,"type":"string"},"licenseNumber":{"nullable":true,"type":"string"},"modelMatchId":{"nullable":true,"type":"string"},"office":{"nullable":true,"type":"string"},"phone":{"nullable":true,"type":"string"},"sellerUnits":{"nullable":true,"type":"number"},"sellerVolume":{"nullable":true,"type":"number"},"state":{"nullable":true,"type":"string"},"totalCompaniesWorkedWith":{"nullable":true,"type":"number"},"totalLendersWorkedWith":{"nullable":true,"type":"number"},"totalOriginatorsWorkedWith":{"nullable":true,"type":"number"},"units":{"nullable":true,"type":"number"},"volume":{"nullable":true,"type":"number"},"zip":{"nullable":true,"type":"string"}},"required":["id"],"type":"object"},"AgentSummaryRequest":{"additionalProperties":false,"properties":{"id":{"type":"string"},"ids":{"items":{"type":"string"},"type":"array"},"period":{"$ref":"#/components/schemas/Period"}},"type":"object"},"AgentTimeSeriesRequest":{"additionalProperties":false,"properties":{"id":{"type":"string"},"ids":{"items":{"type":"string"},"type":"array"},"interval":{"$ref":"#/components/schemas/Interval"},"period":{"$ref":"#/components/schemas/Period"}},"type":"object"},"AlertConditions":{"properties":{"epoThresholdDays":{"description":"Max days since loan close for an early-payoff alert.","example":180,"type":"integer"},"refiRateThreshold":{"description":"Minimum loan rate (%) before a refi-risk alert fires.","example":7,"type":"number"}},"type":"object"},"AlertConditionsResponse":{"properties":{"data":{"properties":{"conditions":{"$ref":"#/components/schemas/AlertConditions"},"emailEnabled":{"$ref":"#/components/schemas/AlertEnabled"},"enabled":{"$ref":"#/components/schemas/AlertEnabled"}},"required":["enabled","emailEnabled","conditions"],"type":"object"}},"required":["data"],"type":"object"},"AlertDecision":{"properties":{"correlationId":{"type":"string"},"dedupeKey":{"type":"string"},"orgId":{"type":"string"},"payload":{"additionalProperties":{"nullable":true},"properties":{"description":{"type":"string"},"url":{"type":"string"}},"required":["description"],"type":"object"},"triggeredAt":{"type":"string"},"type":{"enum":["area_new_listing","watched_agent_pending","borrower_listed","epo_risk","agent_sale_closed","rate_term_refi_area","watched_sale","watched_property","watched_loan"],"type":"string"},"userId":{"type":"string"}},"required":["userId","type","dedupeKey","payload","triggeredAt"],"type":"object"},"AlertDetectorStatusResponse":{"properties":{"data":{"properties":{"running":{"type":"boolean"},"tasks":{"items":{"properties":{"arn":{"type":"string"},"startedAt":{"type":"string"},"status":{"type":"string"},"stoppedReason":{"type":"string"}},"required":["arn","status"],"type":"object"},"type":"array"}},"required":["running","tasks"],"type":"object"}},"required":["data"],"type":"object"},"AlertDigestItem":{"properties":{"count":{"description":"Total alerts rolled into this digest.","type":"integer"},"id":{"description":"Opaque digest id for mark-read.","type":"string"},"ids":{"description":"The individual alert ids — resolve full detail via the feed.","items":{"type":"string"},"type":"array"},"preview":{"description":"First few human-formatted preview lines.","items":{"type":"string"},"type":"array"},"readAt":{"type":"string"},"triggeredAt":{"type":"string"},"type":{"enum":["area_new_listing","watched_agent_pending","borrower_listed","epo_risk","agent_sale_closed","rate_term_refi_area","watched_sale","watched_property","watched_loan"],"type":"string"}},"required":["id","type","count","ids","preview","triggeredAt"],"type":"object"},"AlertDigestResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/AlertDigestItem"},"type":"array"}},"required":["data"],"type":"object"},"AlertEnabled":{"properties":{"agent_sale_closed":{"type":"boolean"},"area_new_listing":{"type":"boolean"},"borrower_listed":{"type":"boolean"},"epo_risk":{"type":"boolean"},"rate_term_refi_area":{"type":"boolean"},"watched_agent_pending":{"type":"boolean"},"watched_loan":{"type":"boolean"},"watched_property":{"type":"boolean"},"watched_sale":{"type":"boolean"}},"required":["area_new_listing","watched_agent_pending","borrower_listed","epo_risk","agent_sale_closed","rate_term_refi_area","watched_sale","watched_property","watched_loan"],"type":"object"},"AlertLogItem":{"properties":{"id":{"description":"Opaque id for mark-read.","type":"string"},"payload":{"additionalProperties":{"nullable":true},"description":"Human description + optional deep link + typed fields.","properties":{"description":{"type":"string"},"url":{"type":"string"}},"required":["description"],"type":"object"},"readAt":{"type":"string"},"triggeredAt":{"type":"string"},"type":{"enum":["area_new_listing","watched_agent_pending","borrower_listed","epo_risk","agent_sale_closed","rate_term_refi_area","watched_sale","watched_property","watched_loan"],"type":"string"}},"required":["id","type","payload","triggeredAt"],"type":"object"},"AlertLogResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/AlertLogItem"},"type":"array"}},"required":["data"],"type":"object"},"AlertsOkResponse":{"properties":{"data":{"properties":{"ok":{"type":"boolean"}},"required":["ok"],"type":"object"}},"required":["data"],"type":"object"},"AndFilter":{"properties":{"children":{"description":"Array of filter expressions (AND)","items":{"$ref":"#/components/schemas/FilterNode"},"type":"array"},"type":{"enum":["and"],"type":"string"}},"required":["type","children"],"type":"object"},"BooleanFilterValue":{"nullable":true,"type":"boolean"},"BranchCompanyTypeFilterValue":{"anyOf":[{"description":"One of (case-insensitive): BANK, CU, OTHER","enum":["BANK","CU","OTHER"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): BANK, CU, OTHER","enum":["BANK","CU","OTHER"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"BranchDetailResponse":{"properties":{"data":{"$ref":"#/components/schemas/BranchSummary"}},"required":["data"],"type":"object"},"BranchField":{"enum":["company","companyName","companyType","name","nmlsId","city","state","zip","zipCode","licensedState","isAuthorized","volume","units","avgLoanAmount","teamSize","rosterJoined","rosterLeft","producersOnly"],"type":"string"},"BranchFlatFilters":{"additionalProperties":false,"properties":{"affordableHousingTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in qualified affordable-housing tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"affordableHousingTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in qualified census tracts for affordable-housing programs, 0-100 (`{gte:25}` = 27,209 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgAsianPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean Asian (non-Hispanic) share of the population in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgBlackPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean Black (non-Hispanic) share of the population in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgDenialRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean share of mortgage applications denied in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgFamilyIncome":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean median family income of the tracts the entity lent in, in whole dollars. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgHispanicPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean Hispanic or Latino share of the population in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgHomeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean median home value across the tracts the entity lent in, in whole dollars. A neighborhood statistic — not the entity's average loan size, which is `avgLoanAmount`. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgHomeownershipRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean owner-occupied share of housing units in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgHouseholdIncome":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean median household income of the tracts the entity lent in, in whole dollars (e.g. `{lte:60000}`). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgIncomeVsMetroPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean tract income relative to its metro area, where `100` is parity — `{lt:80}` is the CRA low/moderate band, and values legitimately exceed 100 (observed up to 412). NOT a 0-100 share. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgLoanAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"avgLowModHouseholdPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean HUD block-group low/moderate-income HOUSEHOLD share across the tracts the entity lent in, 0-100. A finer-grained measure than `lowModIncomeTractPct`, which counts whole tracts — not a duplicate of it. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMedianAge":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean median age of the population in the tracts the entity lent in, in years. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMilesToCollege":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean straight-line distance to the nearest college, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMilesToSchool":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean straight-line distance from the properties the entity lent on to the nearest school, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMilesToWorship":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean straight-line distance to the nearest place of worship, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMinorityPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean non-white share of the population in the tracts the entity lent in, 0-100 (`{gte:50}` = 63,370 originators). `majorityMinorityTractPct` is the per-tract-threshold form of the same question. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgPopulation":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean population of the tracts the entity lent in. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgPovertyRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean share of the population below the poverty line in the tracts the entity lent in, 0-100. Pass whole percents — `{gte:0.2}` means 0.2%. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgTractApplications":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean number of mortgage applications reported in the tracts the entity lent in, over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgTractLoanVolume":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean mortgage dollar volume reported in the tracts the entity lent in, over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgTractOriginations":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean number of mortgage originations reported in the tracts the entity lent in, over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgWhiteNonHispanicPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean White (non-Hispanic) share of the population in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"city":{"$ref":"#/components/schemas/TextFilterValue"},"company":{"$ref":"#/components/schemas/TextFilterValue"},"companyName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy company-name matching is unreliable (partial names silently return 0). Resolve via instantSearch and filter by `company` (exact company NMLS id) instead. Still functional for now."}]},"companyType":{"$ref":"#/components/schemas/BranchCompanyTypeFilterValue"},"difficultDevelopmentAreaCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in HUD-designated difficult development areas. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"difficultDevelopmentAreaPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in HUD-designated difficult development areas, 0-100 (`{gte:25}` = 93,397 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"distressedTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in distressed-or-underserved tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"distressedTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in distressed-or-underserved nonmetropolitan middle-income tracts, 0-100 (`{gte:25}` = 11,773 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"floodHazardTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in a FEMA special flood hazard area. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"floodHazardTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in a FEMA special flood hazard area, 0-100 (`{gte:25}` = 5,212 originators). `predominantFloodZone` gives the specific zone code. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"isAuthorized":{"$ref":"#/components/schemas/TextFilterValue"},"licensedState":{"$ref":"#/components/schemas/TextFilterValue"},"loCount":{"$ref":"#/components/schemas/NumericFilterValue"},"loansWithCommunityData":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"How many of the entity's loans in the selected period resolved to a neighborhood — the DENOMINATOR every Community Lending share is taken over. Pair it with a share filter (`{gte:25}`, 60,399 originators) so a 100% share off two loans does not read as a 100% share off two hundred. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"lowModIncomeTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans that landed in a low- or moderate-income tract, as a count rather than a share. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"lowModIncomeTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans that landed in a low- or moderate-income tract under the Community Reinvestment Act, 0-100. `{gte:50}` = 'at least half their book is LMI' (36,977 originators, 655 companies, 648 branches). Pass whole percents — `{gte:0.5}` means half of one percent and matches nearly everyone. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"majorityMinorityTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in majority-minority tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"majorityMinorityTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in majority-minority tracts, 0-100 (`{gte:50}` = 65,654 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"mode":{"enum":["and","or"],"type":"string"},"name":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — matches the branch's FULL name exactly (e.g. `Movement Mortgage, LLC, Providence, RI Branch`); a partial name will not match. Resolve via instantSearch and filter by `nmlsId` (exact branch NMLS id) instead."}]},"nmlsId":{"$ref":"#/components/schemas/TextFilterValue"},"opportunityZoneCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in Opportunity Zone tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"opportunityZonePct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in federally designated Opportunity Zone tracts, 0-100 (`{gte:10}` = 33,520 originators — this is a small-share filter, a 50% floor finds almost nobody). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"predominantFloodZone":{"$ref":"#/components/schemas/EntityPredominantFloodZoneFilterValue"},"predominantIncomeLevel":{"$ref":"#/components/schemas/EntityPredominantIncomeLevelFilterValue"},"producersOnly":{"$ref":"#/components/schemas/BooleanFilterValue"},"rosterJoined":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Bound the number of loan officers who joined the branch during the selected period — individuals whose sponsorship with the branch began inside the window. IMPORTANT — this counts LICENSING EVENTS, not confirmed employer moves. A loan officer holds a separate license record for every state they are sponsored in, and this counts each individual whose sponsorship began or ended inside the window, so a single added or lapsed state license registers as an arrival or a departure even when the person's employment did not change. Measured on large lenders: 13-24% of a 12-month `rosterLeft` are still sponsored by the same employer today, and 33-50% of a 12-month `rosterJoined` were already sponsored by it before the window began. Treat both as directional indicators of movement, not as headcounts. `rosterJoined` and `rosterLeft` are measured from the same source on the same window basis, so unlike the retired `loLoss` — which had no arrivals figure computed the same way — the two can legitimately be combined into a churn rate. Both also grow with the window, so a longer period reports more than a shorter one and the periods are comparable in that direction."}]},"rosterLeft":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Bound the number of loan officers who left the branch during the selected period — individuals whose sponsorship with the branch ended inside the window. IMPORTANT — this counts LICENSING EVENTS, not confirmed employer moves. A loan officer holds a separate license record for every state they are sponsored in, and this counts each individual whose sponsorship began or ended inside the window, so a single added or lapsed state license registers as an arrival or a departure even when the person's employment did not change. Measured on large lenders: 13-24% of a 12-month `rosterLeft` are still sponsored by the same employer today, and 33-50% of a 12-month `rosterJoined` were already sponsored by it before the window began. Treat both as directional indicators of movement, not as headcounts. `rosterJoined` and `rosterLeft` are measured from the same source on the same window basis, so unlike the retired `loLoss` — which had no arrivals figure computed the same way — the two can legitimately be combined into a churn rate. Both also grow with the window, so a longer period reports more than a shorter one and the periods are comparable in that direction."}]},"ruralGradient":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean remoteness of the tracts the entity lent in, on an ORDINAL 1-10 scale (1 = metropolitan core, 10 = most remote). This is a code, not a percent — `{gte:7}` selects the deepest-rural books (8,886 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"ruralTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in rural tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"ruralTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in rural tracts, 0-100 (`{gte:50}` = 24,006 originators). `ruralGradient` is the finer, ordinal form. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"state":{"$ref":"#/components/schemas/TextFilterValue"},"teamSize":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Bound the number of loan officers currently attributed to the branch. IMPORTANT — this is a CURRENT headcount snapshot, not a per-period measure. The same value is copied into effectively every period, so subtracting one period's `teamSize` from another's does not measure growth or attrition: it is zero for all but a handful of branches, and on those few it reflects a data artifact rather than a real change. Filtering and sorting on it likewise ignore the selected period. For headcount movement over a window, use `rosterJoined` / `rosterLeft`, which are genuinely per-period."}]},"units":{"$ref":"#/components/schemas/NumericFilterValue"},"usdaEligibleTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in USDA-eligible tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"usdaEligibleTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in tracts eligible for USDA rural housing programs, 0-100 (`{gte:50}` = 90,392 originators). Broader than `ruralTractPct` — eligibility reaches well past what is classified rural. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"volume":{"$ref":"#/components/schemas/NumericFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"ZIP code. Canonical key (matches the `zip` field on the response DTO); `zipCode` is a cross-entity alias kept for parity with loans/sales."}]},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"BranchListRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/BranchFlatFilters"},"lenderFilters":{"items":{"$ref":"#/components/schemas/LenderFilterEntry"},"type":"array"},"lenderMatchMode":{"$ref":"#/components/schemas/LenderMatchMode"},"pagination":{"$ref":"#/components/schemas/Pagination"},"period":{"allOf":[{"$ref":"#/components/schemas/Period"},{"description":"Period for branch production metrics (default: last12Months). Applies to `volume`, `units`, `avgLoanAmount`, `rosterJoined` and `rosterLeft`. It does NOT apply to `teamSize`, which is a current snapshot and reads the same on every period."}]},"sort":{"items":{"properties":{"field":{"$ref":"#/components/schemas/BranchField"},"order":{"$ref":"#/components/schemas/SortOrder"}},"required":["field"],"type":"object"},"type":"array"}},"type":"object"},"BranchListResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/BranchSummary"},"type":"array"},"locationNormalizations":{"description":"How each location filter value resolved. Present when a `city`/`county`/`state`/`zip` filter was supplied.","items":{"$ref":"#/components/schemas/LocationNormalization"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"BranchManager":{"properties":{"name":{"nullable":true,"type":"string"},"nmlsId":{"nullable":true,"type":"string"}},"type":"object"},"BranchSummary":{"properties":{"avgLoanAmount":{"nullable":true,"type":"number"},"city":{"nullable":true,"type":"string"},"communityLending":{"$ref":"#/components/schemas/EntityCommunityLending"},"companyName":{"nullable":true,"type":"string"},"companyNmlsId":{"nullable":true,"type":"string"},"companyType":{"nullable":true,"type":"string"},"coordinates":{"nullable":true,"properties":{"lat":{"type":"number"},"lon":{"type":"number"}},"required":["lat","lon"],"type":"object"},"id":{"type":"string"},"isAuthorized":{"nullable":true,"type":"boolean"},"licensedStates":{"description":"Licensed states (populated on the detail route only)","items":{"type":"string"},"nullable":true,"type":"array"},"loCount":{"nullable":true,"type":"number"},"managerCount":{"nullable":true,"type":"number"},"managers":{"description":"Branch managers. List rows carry NMLS ids only; the detail route adds manager names.","items":{"$ref":"#/components/schemas/BranchManager"},"nullable":true,"type":"array"},"name":{"nullable":true,"type":"string"},"nmlsId":{"nullable":true,"type":"string"},"purchasePct":{"nullable":true,"type":"number"},"refinancePct":{"nullable":true,"type":"number"},"rosterJoined":{"description":"Loan officers who joined the branch during the selected period — individuals whose sponsorship with the branch began inside the window. IMPORTANT — this counts LICENSING EVENTS, not confirmed employer moves. A loan officer holds a separate license record for every state they are sponsored in, and this counts each individual whose sponsorship began or ended inside the window, so a single added or lapsed state license registers as an arrival or a departure even when the person's employment did not change. Measured on large lenders: 13-24% of a 12-month `rosterLeft` are still sponsored by the same employer today, and 33-50% of a 12-month `rosterJoined` were already sponsored by it before the window began. Treat both as directional indicators of movement, not as headcounts. `rosterJoined` and `rosterLeft` are measured from the same source on the same window basis, so unlike the retired `loLoss` — which had no arrivals figure computed the same way — the two can legitimately be combined into a churn rate. Both also grow with the window, so a longer period reports more than a shorter one and the periods are comparable in that direction.","nullable":true,"type":"number"},"rosterLeft":{"description":"Loan officers who left the branch during the selected period — individuals whose sponsorship with the branch ended inside the window. IMPORTANT — this counts LICENSING EVENTS, not confirmed employer moves. A loan officer holds a separate license record for every state they are sponsored in, and this counts each individual whose sponsorship began or ended inside the window, so a single added or lapsed state license registers as an arrival or a departure even when the person's employment did not change. Measured on large lenders: 13-24% of a 12-month `rosterLeft` are still sponsored by the same employer today, and 33-50% of a 12-month `rosterJoined` were already sponsored by it before the window began. Treat both as directional indicators of movement, not as headcounts. `rosterJoined` and `rosterLeft` are measured from the same source on the same window basis, so unlike the retired `loLoss` — which had no arrivals figure computed the same way — the two can legitimately be combined into a churn rate. Both also grow with the window, so a longer period reports more than a shorter one and the periods are comparable in that direction.","nullable":true,"type":"number"},"state":{"nullable":true,"type":"string"},"street":{"nullable":true,"type":"string"},"teamSize":{"description":"Loan officers currently attributed to this branch. IMPORTANT — this is a CURRENT headcount snapshot, not a per-period measure. The same value is copied into effectively every period, so subtracting one period's `teamSize` from another's does not measure growth or attrition: it is zero for all but a handful of branches, and on those few it reflects a data artifact rather than a real change. Filtering and sorting on it likewise ignore the selected period. For headcount movement over a window, use `rosterJoined` / `rosterLeft`, which are genuinely per-period.","nullable":true,"type":"number"},"tradenames":{"items":{"type":"string"},"nullable":true,"type":"array"},"units":{"description":"Branch-level loan units for the selected period","nullable":true,"type":"number"},"volume":{"description":"Branch-level loan volume for the selected period","nullable":true,"type":"number"},"zip":{"nullable":true,"type":"string"}},"required":["id"],"type":"object"},"BreakdownItem":{"properties":{"excluded":{"description":"How many of this bucket's documents the volume guard excluded — documents that carry the money field but whose value is an out-of-range fill. Compare against `units` to see what share of the bucket `volume` was actually computed over: a bucket can show many units and still sum a small fraction of them. Absent when the entity's money column is unguarded (the sales-backed agent breakdowns), where nothing can be excluded.","type":"number"},"id":{"description":"Machine value behind `label` for breakdowns whose bucket key is an id rather than a name (today: `lenders`, where `label` is the dictionary display name and `id` is the normalized lender key). Pass `id` — not `label` — back as a `lender` filter value. Absent on name-keyed breakdowns, where `label` is already the machine value.","type":"string"},"label":{"description":"Bucket label/key","type":"string"},"name":{"description":"Human-readable name for the bucket when `label` is an entity id (e.g. a broker NMLS id resolved to its company name). Absent when unresolved or not an id-keyed breakdown.","type":"string"},"pctUnits":{"description":"Percentage of total units","type":"number"},"pctVolume":{"description":"Percentage of total volume","type":"number"},"units":{"description":"Number of transactions","type":"number"},"volume":{"description":"Total dollar volume","type":"number"}},"required":["label","units","volume","pctUnits","pctVolume"],"type":"object"},"BreakdownRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"borrowerStatus":{"$ref":"#/components/schemas/LoanBorrowerStatusFilterValue"},"broker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Broker shop NMLS id (digits only). A broker is a company — resolve a broker name to its NMLS id via instantSearch (or listCompanies)."}]},"buyerEntityType":{"$ref":"#/components/schemas/BooleanFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"conforming":{"$ref":"#/components/schemas/BooleanFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County name (e.g. \"Broward\") or 5-digit FIPS code. Names resolve to FIPS server-side; include a `state` filter to disambiguate."}]},"currentBalance":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated remaining principal balance (~19% populated). Approximate current equity as `homeValue` (AVM) minus this."}]},"employer":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Employer/company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Point-in-time equity recorded on the loan (sparse, ~10%). NOT a live current-equity figure. For HELOC/cash-out targeting on up-to-date equity, use properties search (listProperties) instead — its equity is far better populated and current."}]},"excludeBroker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans brokered by this broker-shop NMLS id (digits only) — the inverse of `broker`."}]},"excludeCity":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this city — the inverse of `city`."}]},"excludeLender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans from this lender ID (\"everyone but X\") — the inverse of `lender`, same id contract (resolve via instantSearch/listLenders). Loans with no lender stay in the results."}]},"excludeLoanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans funded by this company NMLS id (digits only) — the inverse of `loanCompany`."}]},"excludeOriginator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans with this originator NMLS id (digits only) — the inverse of `originator`. Common for 'everyone but my own shop' lists."}]},"excludeState":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this state (2-letter code, e.g. \"CA\") — the inverse of `state`. For \"everywhere but this state\" lists."}]},"excludeZipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this ZIP code — the inverse of `zipCode`."}]},"fips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exact 5-digit county FIPS code (no name resolution) — the code-only escape hatch alongside `county`."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"homeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"AVM (automated valuation) at the linked property (~26%, MLS-linked). Pair with `currentBalance` to approximate current equity."}]},"includeUnknownOriginator":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Include loans that have no originator NMLS id. Omitted/false (default): such loans are excluded — the vast majority are pre-2016 public records with no linkable originator. true: include them. Note that the default scopes results to loans with a known originator (~2016+ recordings)."}]},"interestRate":{"$ref":"#/components/schemas/NumericFilterValue"},"lender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender ID — the normalized lender-dictionary key, NOT a fuzzy name match. Resolve a lender via instantSearch (or listLenders) and pass the `id` it returns (e.g. \"mortgage_rocket\" or \"mortgage rocket\"). Underscores and letter case are normalized, so either id surface works. A stored normalized lender name (what the `slice: \"lender\"` chart buckets emit) is also accepted, so a chart bucket key filters directly. A value that is neither returns 400 rather than silently matching nothing — to search by lender NAME, use `lenderName`."}]},"lenderName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender name as recorded on the loan document — fuzzy, all-terms match (e.g. \"Fifth Third\"). The name counterpart to the exact-id `lender` filter; use `lender` when you have a resolved id, and this when you only have a name."}]},"loanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Funding/loan company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"loanType":{"$ref":"#/components/schemas/LoanTypeFilterValue"},"ltvAtOrigination":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan-to-value at ORIGINATION (sparse). This is not a current LTV — there is no stored current-LTV field on loans."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"mortgageDate":{"$ref":"#/components/schemas/DateFilterValue"},"originator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Loan originator NMLS id (digits only). To search by name use `originatorName`, or resolve a name to its id via instantSearch."}]},"originatorName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (same originator can return wildly different counts by name string). Resolve the loan officer via instantSearch and filter by `originator` (exact NMLS id) instead. Still functional for now."}]},"saleDate":{"$ref":"#/components/schemas/DateFilterValue"},"salePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"transactionType":{"$ref":"#/components/schemas/LoanTransactionTypeFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zipCode` — same ZIP filter, accepted for cross-entity key parity."}]},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"pagination":{"$ref":"#/components/schemas/Pagination"},"period":{"$ref":"#/components/schemas/Period"},"sort":{"$ref":"#/components/schemas/BreakdownSort"}},"type":"object"},"BreakdownResponse":{"properties":{"cursor":{"description":"Opaque cursor for the next page; absent when this is the last page.","type":"string"},"data":{"items":{"$ref":"#/components/schemas/BreakdownItem"},"type":"array"},"total":{"description":"Number of buckets returned","type":"number"},"totals":{"description":"Grand totals across all data","properties":{"excluded":{"description":"Documents the volume guard excluded across the whole scope — the grand-total counterpart of a bucket's `excluded`, and the same figure `/analytics/summary` reports as `current.excluded.volume` for an equivalent query. Absent when the money column is unguarded.","type":"number"},"units":{"type":"number"},"volume":{"type":"number"}},"required":["units","volume"],"type":"object"},"truncated":{"description":"True when more buckets exist beyond this page. Page through with `cursor`, or sort by `label` to enumerate the full key space.","type":"boolean"}},"required":["data","total"],"type":"object"},"BreakdownSort":{"items":{"properties":{"field":{"description":"One of (case-insensitive): volume, units, label, pctVolume, pctUnits","enum":["volume","units","label","pctVolume","pctUnits"],"type":"string"},"order":{"$ref":"#/components/schemas/SortOrder"}},"required":["field"],"type":"object"},"type":"array"},"BulkDeliveryForbidden":{"properties":{"entitlementKey":{"description":"Entitlement that would lift the cap. Contact support to request a limit increase.","type":"string"},"error":{"enum":["entitlement_missing"],"type":"string"},"estimatedTotal":{"description":"Rows the query matched — what pushed it over `maxRows`.","minimum":0,"type":"integer"},"maxRows":{"description":"Row ceiling that applied to this request, i.e. the deliverable limit without the entitlement.","exclusiveMinimum":true,"minimum":0,"type":"integer"},"message":{"type":"string"}},"required":["error","entitlementKey","estimatedTotal","maxRows","message"],"type":"object"},"BulkDeliveryFormat":{"description":"Output file format for the delivered dataset. Every format contains the same rows — the entity's list/summary DTO (e.g. `LoanSummary`), one record per row. `ndjson`: gzipped newline-delimited JSON (`application/x-ndjson`, `.ndjson.gz`). `json`: a single JSON array (`application/json`, `.json`). `csv`: RFC 4180 (`text/csv`, `.csv`). `parquet`: typed columnar Apache Parquet — scalar fields keep their DTO types, nested fields are JSON-encoded strings (`application/vnd.apache.parquet`, `.parquet`).","enum":["ndjson","json","csv","parquet"],"example":"parquet","type":"string"},"BulkDeliveryInsufficientCredits":{"properties":{"balance":{"description":"Remaining credit balance the charge saw.","type":"number"},"cost":{"description":"Credits the request asked for.","type":"number"},"error":{"enum":["payment_required"],"type":"string"},"message":{"description":"Human-readable explanation of the decline.","type":"string"},"reason":{"description":"Why the charge was declined, when known: `out_of_credits` (balance empty) vs. `limit_reached` (a spend cap was hit).","enum":["out_of_credits","limit_reached"],"type":"string"}},"required":["error","balance","cost"],"type":"object"},"BulkDeliveryPreflightExceeded":{"properties":{"error":{"enum":["delivery_exceeds_max_rows"],"type":"string"},"estimatedTotal":{"minimum":0,"type":"integer"},"maxRows":{"exclusiveMinimum":true,"minimum":0,"type":"integer"}},"required":["error","estimatedTotal","maxRows"],"type":"object"},"BulkDeliveryStatusResponse":{"properties":{"bytes":{"minimum":0,"type":"integer"},"chargedCount":{"description":"Delivered-row count that was billed.","minimum":0,"type":"integer"},"completedAt":{"type":"string"},"creditLedgerId":{"description":"Credit-ledger entry id for this job's debit. Absent if billing didn't land.","type":"string"},"creditsCharged":{"description":"Credits debited for this job (1 credit / 100 rows). Absent until the job completes; absent on a failed billing call.","minimum":0,"type":"number"},"downloadUrl":{"description":"Stable, shareable download link for the completed dataset. Forces a file download (with a friendly filename) and stays valid for 7 days after completion. Present once `status` is `completed`. This is the link to hand to a user or send by email.","type":"string"},"entityType":{"type":"string"},"error":{"type":"string"},"estimatedTotal":{"minimum":0,"type":"integer"},"format":{"$ref":"#/components/schemas/BulkDeliveryFormat"},"jobId":{"type":"string"},"processed":{"minimum":0,"type":"integer"},"resultsUrl":{"description":"Direct download URL for the completed dataset. Long-lived per request but changes on each poll; prefer `downloadUrl` for a stable link to share.","type":"string"},"startedAt":{"type":"string"},"status":{"enum":["queued","running","completed","failed"],"type":"string"}},"required":["jobId","status"],"type":"object"},"BulkDeliverySubmitResponse":{"properties":{"entityType":{"type":"string"},"estimatedTotal":{"minimum":0,"type":"integer"},"format":{"$ref":"#/components/schemas/BulkDeliveryFormat"},"jobId":{"type":"string"},"maxRows":{"exclusiveMinimum":true,"minimum":0,"type":"integer"},"status":{"enum":["queued"],"type":"string"}},"required":["jobId","status","entityType","format","estimatedTotal","maxRows"],"type":"object"},"CacheScope":{"description":"Which row kind(s) to scan. Default `both`.","enum":["internal","member","both"],"type":"string"},"ChartBucket":{"properties":{"count":{"description":"How many documents this bucket was built from — the denominator behind `value`, published whatever the measure. It is the sample size of an average, the transaction count behind a `volume` sum, and (for `measure: \"units\"`) `value` itself. Present on every bucket. Distinct from `excluded`, which reports how many of these documents a guarded measure's sentinel filter then dropped: a bucket can look well-populated here and still average over far fewer.","type":"number"},"excluded":{"description":"How many of this bucket's documents the measure's sentinel guard excluded — documents that carry the field but whose value is an out-of-range fill. Additive and optional: absent when the measure is unguarded (a document count, or a field with no fill values). Present per BUCKET because exclusion is not uniform — one period or slice can be almost entirely fill values while its neighbors are clean, and a single response-level total would hide exactly that.","type":"number"},"id":{"description":"Machine value behind `label` when the bucket key is an id rather than a name (today: the `lender` slice/segment, where `label` is the dictionary display name). Pass `id` — not `label` — back as a `lender` filter value. Absent on slices whose `label` is already the machine value.","type":"string"},"label":{"type":"string"},"segments":{"items":{"$ref":"#/components/schemas/ChartSegment"},"type":"array"},"value":{"type":"number"}},"required":["label","value","count"],"type":"object"},"ChartMeasure":{"default":"units","description":"Which metric each bar reports — and, with one exception, NOT what the bars are ranked by. Ranking is by transaction count unless you explicitly pass `volume`, which ranks by dollars instead. Defaults to `units`, so \"top originators\" means the busiest rather than the biggest. The average measures deliberately rank by count too: ordering a high-cardinality slice by its own mean returns whichever one-transaction buckets happened to score highest, so \"top zips by average rate\" would mean \"zips with one weird loan\" — ranked by count it means \"the busiest zips, with their rates\". Every bucket publishes its own `count`, so the sample size behind a value is never implicit.","enum":["volume","units","avgSalePrice","avgListPrice"],"type":"string"},"ChartResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/ChartBucket"},"type":"array"},"measure":{"type":"string"},"segment":{"nullable":true,"type":"string"},"slice":{"type":"string"}},"required":["measure","slice","segment","data"],"type":"object"},"ChartSegment":{"properties":{"label":{"type":"string"},"value":{"type":"number"}},"required":["label","value"],"type":"object"},"ClearAlertHistoryRequest":{"properties":{"detectors":{"description":"Limit the wipe to these alert types; all history when omitted.","items":{"enum":["area_new_listing","watched_agent_pending","borrower_listed","epo_risk","agent_sale_closed","rate_term_refi_area","watched_sale","watched_property","watched_loan"],"type":"string"},"type":"array"}},"type":"object"},"ClearAlertHistoryResponse":{"properties":{"data":{"properties":{"dedupDeleted":{"type":"integer"},"digestDeleted":{"type":"integer"},"logDeleted":{"type":"integer"}},"required":["dedupDeleted","logDeleted","digestDeleted"],"type":"object"}},"required":["data"],"type":"object"},"CompanyBranch":{"properties":{"branchNmlsId":{"nullable":true,"type":"string"},"city":{"nullable":true,"type":"string"},"companyName":{"nullable":true,"type":"string"},"companyNmlsId":{"nullable":true,"type":"string"},"id":{"type":"string"},"isAuthorized":{"nullable":true,"type":"boolean"},"licensedStates":{"items":{"type":"string"},"nullable":true,"type":"array"},"location":{"nullable":true,"properties":{"lat":{"type":"number"},"lon":{"type":"number"}},"required":["lat","lon"],"type":"object"},"managers":{"nullable":true},"name":{"nullable":true,"type":"string"},"postalCode":{"nullable":true,"type":"string"},"state":{"nullable":true,"type":"string"},"street":{"nullable":true,"type":"string"},"tradeNames":{"items":{"type":"string"},"nullable":true,"type":"array"}},"required":["id"],"type":"object"},"CompanyBranchesResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/CompanyBranch"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"CompanyChartRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"borrowerStatus":{"$ref":"#/components/schemas/LoanBorrowerStatusFilterValue"},"broker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Broker shop NMLS id (digits only). A broker is a company — resolve a broker name to its NMLS id via instantSearch (or listCompanies)."}]},"buyerEntityType":{"$ref":"#/components/schemas/BooleanFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"conforming":{"$ref":"#/components/schemas/BooleanFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County name (e.g. \"Broward\") or 5-digit FIPS code. Names resolve to FIPS server-side; include a `state` filter to disambiguate."}]},"currentBalance":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated remaining principal balance (~19% populated). Approximate current equity as `homeValue` (AVM) minus this."}]},"employer":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Employer/company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Point-in-time equity recorded on the loan (sparse, ~10%). NOT a live current-equity figure. For HELOC/cash-out targeting on up-to-date equity, use properties search (listProperties) instead — its equity is far better populated and current."}]},"excludeBroker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans brokered by this broker-shop NMLS id (digits only) — the inverse of `broker`."}]},"excludeCity":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this city — the inverse of `city`."}]},"excludeLender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans from this lender ID (\"everyone but X\") — the inverse of `lender`, same id contract (resolve via instantSearch/listLenders). Loans with no lender stay in the results."}]},"excludeLoanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans funded by this company NMLS id (digits only) — the inverse of `loanCompany`."}]},"excludeOriginator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans with this originator NMLS id (digits only) — the inverse of `originator`. Common for 'everyone but my own shop' lists."}]},"excludeState":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this state (2-letter code, e.g. \"CA\") — the inverse of `state`. For \"everywhere but this state\" lists."}]},"excludeZipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this ZIP code — the inverse of `zipCode`."}]},"fips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exact 5-digit county FIPS code (no name resolution) — the code-only escape hatch alongside `county`."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"homeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"AVM (automated valuation) at the linked property (~26%, MLS-linked). Pair with `currentBalance` to approximate current equity."}]},"includeUnknownOriginator":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Include loans that have no originator NMLS id. Omitted/false (default): such loans are excluded — the vast majority are pre-2016 public records with no linkable originator. true: include them. Note that the default scopes results to loans with a known originator (~2016+ recordings)."}]},"interestRate":{"$ref":"#/components/schemas/NumericFilterValue"},"lender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender ID — the normalized lender-dictionary key, NOT a fuzzy name match. Resolve a lender via instantSearch (or listLenders) and pass the `id` it returns (e.g. \"mortgage_rocket\" or \"mortgage rocket\"). Underscores and letter case are normalized, so either id surface works. A stored normalized lender name (what the `slice: \"lender\"` chart buckets emit) is also accepted, so a chart bucket key filters directly. A value that is neither returns 400 rather than silently matching nothing — to search by lender NAME, use `lenderName`."}]},"lenderName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender name as recorded on the loan document — fuzzy, all-terms match (e.g. \"Fifth Third\"). The name counterpart to the exact-id `lender` filter; use `lender` when you have a resolved id, and this when you only have a name."}]},"loanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Funding/loan company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"loanType":{"$ref":"#/components/schemas/LoanTypeFilterValue"},"ltvAtOrigination":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan-to-value at ORIGINATION (sparse). This is not a current LTV — there is no stored current-LTV field on loans."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"mortgageDate":{"$ref":"#/components/schemas/DateFilterValue"},"originator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Loan originator NMLS id (digits only). To search by name use `originatorName`, or resolve a name to its id via instantSearch."}]},"originatorName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (same originator can return wildly different counts by name string). Resolve the loan officer via instantSearch and filter by `originator` (exact NMLS id) instead. Still functional for now."}]},"saleDate":{"$ref":"#/components/schemas/DateFilterValue"},"salePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"transactionType":{"$ref":"#/components/schemas/LoanTransactionTypeFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zipCode` — same ZIP filter, accepted for cross-entity key parity."}]},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"measure":{"$ref":"#/components/schemas/ChartMeasure"},"nmlsId":{"type":"string"},"nmlsIds":{"items":{"type":"string"},"type":"array"},"period":{"$ref":"#/components/schemas/Period"},"slice":{"$ref":"#/components/schemas/CompanySlice"}},"required":["slice"],"type":"object"},"CompanyDetail":{"allOf":[{"$ref":"#/components/schemas/CompanySummary"},{"properties":{"communityLending":{"$ref":"#/components/schemas/EntityCommunityLending"},"registration":{"$ref":"#/components/schemas/CompanyRegistration"}},"type":"object"}]},"CompanyDetailResponse":{"properties":{"data":{"$ref":"#/components/schemas/CompanyDetail"}},"required":["data"],"type":"object"},"CompanyFootprintFilter":{"additionalProperties":false,"properties":{"avgLoanAmount":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"Mean loan size funded by this lender."}]},"dimension":{"description":"Which footprint to address. Only `lender` is available for companies — it is inferred from a `lender` key, so you rarely pass this. Name it to ask the ANY-lender question (`{dimension:'lender', volume:{gte:50000000}}` = 'some single lender they sent $50M to'). A geographic dimension is a 400 naming the per-company markets endpoint, which live-aggregates that answer.","enum":["zip","city","county","state","lender"],"type":"string"},"lender":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"description":"Funding lender, as an id from `listLenders` or `instantSearch`. Lender names are stored in a normalized dictionary form, so a typed name does not match — resolve it first. Several values UNION."},"not":{"description":"Invert the whole entry: match companies with NO lender relationship matching it (e.g. 'does not send loans to this lender').","type":"boolean"},"product":{"allOf":[{"$ref":"#/components/schemas/FootprintProductFilter"},{"description":"Correlate a product INSIDE this lender relationship — '$1M of FHA through this lender'."}]},"shareOfVolume":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"This lender's share of the company's total volume for the period, as a 0–100 PERCENT (not a 0–1 fraction). `{gte:50}` = 'at least half their book goes through this lender'."}]},"units":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"Loan count funded by this lender during the selected period."}]},"volume":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"Dollar volume funded BY this lender during the selected period — evaluated inside the lender's own bucket, not against the company's total."}]}},"type":"object"},"CompanyListRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"affordableHousingTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in qualified affordable-housing tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"affordableHousingTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in qualified census tracts for affordable-housing programs, 0-100 (`{gte:25}` = 27,209 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgAsianPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean Asian (non-Hispanic) share of the population in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgBlackPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean Black (non-Hispanic) share of the population in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgDenialRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean share of mortgage applications denied in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgFamilyIncome":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean median family income of the tracts the entity lent in, in whole dollars. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgHispanicPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean Hispanic or Latino share of the population in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgHomeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean median home value across the tracts the entity lent in, in whole dollars. A neighborhood statistic — not the entity's average loan size, which is `avgLoanAmount`. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgHomeownershipRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean owner-occupied share of housing units in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgHouseholdIncome":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean median household income of the tracts the entity lent in, in whole dollars (e.g. `{lte:60000}`). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgIncomeVsMetroPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean tract income relative to its metro area, where `100` is parity — `{lt:80}` is the CRA low/moderate band, and values legitimately exceed 100 (observed up to 412). NOT a 0-100 share. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgLoanAmount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Bound the company's mean loan size for the selected period, derived from TOTAL production across ALL markets — NOT scoped to any geographic filter (`city`/`state`/`zip`/`zipCode`/`geoPoint`) in this request. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank companies by it. There are two ways to get production for a geography: `POST /companies/{nmlsId}/markets` breaks ONE company's production out by market, and `POST /loans/analytics/chart` with `measure: \"volume\"`, `slice: \"loanCompany\"` and a geographic filter answers the reverse — the companies that actually produced in that geography, each with the volume they produced there."}]},"avgLowModHouseholdPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean HUD block-group low/moderate-income HOUSEHOLD share across the tracts the entity lent in, 0-100. A finer-grained measure than `lowModIncomeTractPct`, which counts whole tracts — not a duplicate of it. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMedianAge":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean median age of the population in the tracts the entity lent in, in years. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMilesToCollege":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean straight-line distance to the nearest college, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMilesToSchool":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean straight-line distance from the properties the entity lent on to the nearest school, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMilesToWorship":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean straight-line distance to the nearest place of worship, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMinorityPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean non-white share of the population in the tracts the entity lent in, 0-100 (`{gte:50}` = 63,370 originators). `majorityMinorityTractPct` is the per-tract-threshold form of the same question. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgPopulation":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean population of the tracts the entity lent in. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgPovertyRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean share of the population below the poverty line in the tracts the entity lent in, 0-100. Pass whole percents — `{gte:0.2}` means 0.2%. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgTractApplications":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean number of mortgage applications reported in the tracts the entity lent in, over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgTractLoanVolume":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean mortgage dollar volume reported in the tracts the entity lent in, over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgTractOriginations":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean number of mortgage originations reported in the tracts the entity lent in, over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgWhiteNonHispanicPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean White (non-Hispanic) share of the population in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"branchCount":{"$ref":"#/components/schemas/NumericFilterValue"},"city":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Registered business address CITY — where the company is headquartered, NOT where it produced loans. This matches companies whose registered address is in this city; a company headquartered elsewhere is excluded no matter how much it lends here, and a company headquartered here is returned even if it produced nothing here. The row's `volume`/`units`/`avgLoanAmount` remain national totals, so a city filter combined with the default `volume` sort ranks the largest national producers that happen to be headquartered in this city. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank companies by it. There are two ways to get production for a geography: `POST /companies/{nmlsId}/markets` breaks ONE company's production out by market, and `POST /loans/analytics/chart` with `measure: \"volume\"`, `slice: \"loanCompany\"` and a geographic filter answers the reverse — the companies that actually produced in that geography, each with the volume they produced there."}]},"companyType":{"$ref":"#/components/schemas/CompanyTypeFilterValue"},"difficultDevelopmentAreaCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in HUD-designated difficult development areas. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"difficultDevelopmentAreaPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in HUD-designated difficult development areas, 0-100 (`{gte:25}` = 93,397 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"distressedTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in distressed-or-underserved tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"distressedTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in distressed-or-underserved nonmetropolitan middle-income tracts, 0-100 (`{gte:25}` = 11,773 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"floodHazardTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in a FEMA special flood hazard area. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"floodHazardTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in a FEMA special flood hazard area, 0-100 (`{gte:25}` = 5,212 originators). `predominantFloodZone` gives the specific zone code. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"geoPoint":{"allOf":[{"$ref":"#/components/schemas/GeoFilterValue"},{"description":"Radius search around a point, over the company's registered business address — it finds companies HEADQUARTERED within the radius, NOT companies that produced loans there. A company headquartered outside the radius is excluded no matter how much it lends inside it, and one headquartered inside is returned even if it produced nothing there. The row's `volume`/`units`/`avgLoanAmount` remain national totals, so a radius search combined with the default `volume` sort ranks the largest national producers that happen to be headquartered nearby. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank companies by it. There are two ways to get production for a geography: `POST /companies/{nmlsId}/markets` breaks ONE company's production out by market, and `POST /loans/analytics/chart` with `measure: \"volume\"`, `slice: \"loanCompany\"` and a geographic filter answers the reverse — the companies that actually produced in that geography, each with the volume they produced there."}]},"loCount":{"$ref":"#/components/schemas/NumericFilterValue"},"loansWithCommunityData":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"How many of the entity's loans in the selected period resolved to a neighborhood — the DENOMINATOR every Community Lending share is taken over. Pair it with a share filter (`{gte:25}`, 60,399 originators) so a 100% share off two loans does not read as a 100% share off two hundred. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"lowModIncomeTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans that landed in a low- or moderate-income tract, as a count rather than a share. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"lowModIncomeTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans that landed in a low- or moderate-income tract under the Community Reinvestment Act, 0-100. `{gte:50}` = 'at least half their book is LMI' (36,977 originators, 655 companies, 648 branches). Pass whole percents — `{gte:0.5}` means half of one percent and matches nearly everyone. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"majorityMinorityTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in majority-minority tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"majorityMinorityTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in majority-minority tracts, 0-100 (`{gte:50}` = 65,654 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"mode":{"enum":["and","or"],"type":"string"},"name":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (name pollution silently returns unrelated companies). Resolve via instantSearch and filter by `nmlsId` (exact NMLS id) instead. Still functional for now."}]},"nmlsId":{"$ref":"#/components/schemas/TextFilterValue"},"opportunityZoneCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in Opportunity Zone tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"opportunityZonePct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in federally designated Opportunity Zone tracts, 0-100 (`{gte:10}` = 33,520 originators — this is a small-share filter, a 50% floor finds almost nobody). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"predominantFloodZone":{"$ref":"#/components/schemas/EntityPredominantFloodZoneFilterValue"},"predominantIncomeLevel":{"$ref":"#/components/schemas/EntityPredominantIncomeLevelFilterValue"},"producersOnly":{"$ref":"#/components/schemas/BooleanFilterValue"},"rosterJoined":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Bound the number of loan officers who joined the company during the selected period — individuals whose sponsorship with the company began inside the window. IMPORTANT — this counts LICENSING EVENTS, not confirmed employer moves. A loan officer holds a separate license record for every state they are sponsored in, and this counts each individual whose sponsorship began or ended inside the window, so a single added or lapsed state license registers as an arrival or a departure even when the person's employment did not change. Measured on large lenders: 13-24% of a 12-month `rosterLeft` are still sponsored by the same employer today, and 33-50% of a 12-month `rosterJoined` were already sponsored by it before the window began. Treat both as directional indicators of movement, not as headcounts. `rosterJoined` and `rosterLeft` are measured from the same source on the same window basis, so unlike the retired `loLoss` — which had no arrivals figure computed the same way — the two can legitimately be combined into a churn rate. Both also grow with the window, so a longer period reports more than a shorter one and the periods are comparable in that direction."}]},"rosterLeft":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Bound the number of loan officers who left the company during the selected period — individuals whose sponsorship with the company ended inside the window. IMPORTANT — this counts LICENSING EVENTS, not confirmed employer moves. A loan officer holds a separate license record for every state they are sponsored in, and this counts each individual whose sponsorship began or ended inside the window, so a single added or lapsed state license registers as an arrival or a departure even when the person's employment did not change. Measured on large lenders: 13-24% of a 12-month `rosterLeft` are still sponsored by the same employer today, and 33-50% of a 12-month `rosterJoined` were already sponsored by it before the window began. Treat both as directional indicators of movement, not as headcounts. `rosterJoined` and `rosterLeft` are measured from the same source on the same window basis, so unlike the retired `loLoss` — which had no arrivals figure computed the same way — the two can legitimately be combined into a churn rate. Both also grow with the window, so a longer period reports more than a shorter one and the periods are comparable in that direction."}]},"ruralGradient":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean remoteness of the tracts the entity lent in, on an ORDINAL 1-10 scale (1 = metropolitan core, 10 = most remote). This is a code, not a percent — `{gte:7}` selects the deepest-rural books (8,886 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"ruralTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in rural tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"ruralTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in rural tracts, 0-100 (`{gte:50}` = 24,006 originators). `ruralGradient` is the finer, ordinal form. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"state":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Registered business address STATE — where the company is headquartered, NOT where it produced loans. This matches companies whose registered address is in this state; a company headquartered elsewhere is excluded no matter how much it lends here, and a company headquartered here is returned even if it produced nothing here. The row's `volume`/`units`/`avgLoanAmount` remain national totals, so a state filter combined with the default `volume` sort ranks the largest national producers that happen to be headquartered in this state — not the largest producers in it. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank companies by it. There are two ways to get production for a geography: `POST /companies/{nmlsId}/markets` breaks ONE company's production out by market, and `POST /loans/analytics/chart` with `measure: \"volume\"`, `slice: \"loanCompany\"` and a geographic filter answers the reverse — the companies that actually produced in that geography, each with the volume they produced there."}]},"teamSize":{"$ref":"#/components/schemas/NumericFilterValue"},"units":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Bound the company's TOTAL loan count for the selected period across ALL markets — the same national total the response `units` returns, NOT scoped to any geographic filter (`city`/`state`/`zip`/`zipCode`/`geoPoint`) in this request, exactly as described on the `volume` filter. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank companies by it. There are two ways to get production for a geography: `POST /companies/{nmlsId}/markets` breaks ONE company's production out by market, and `POST /loans/analytics/chart` with `measure: \"volume\"`, `slice: \"loanCompany\"` and a geographic filter answers the reverse — the companies that actually produced in that geography, each with the volume they produced there."}]},"usdaEligibleTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in USDA-eligible tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"usdaEligibleTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in tracts eligible for USDA rural housing programs, 0-100 (`{gte:50}` = 90,392 originators). Broader than `ruralTractPct` — eligibility reaches well past what is classified rural. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"volume":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Bound the company's TOTAL dollar production for the selected period across ALL markets — this is the same national total the response `volume` returns, and it is NOT scoped to any geographic filter (`city`/`state`/`zip`/`zipCode`/`geoPoint`) in this request. Combined with one of those filters it means 'national volume at least this large, AND headquartered in that place' — not 'produced this much there'. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank companies by it. There are two ways to get production for a geography: `POST /companies/{nmlsId}/markets` breaks ONE company's production out by market, and `POST /loans/analytics/chart` with `measure: \"volume\"`, `slice: \"loanCompany\"` and a geographic filter answers the reverse — the companies that actually produced in that geography, each with the volume they produced there."}]},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Registered business address ZIP code — where the company is headquartered, NOT where it produced loans, with the same caveats as `state` and `city`: a company headquartered elsewhere is excluded however much it lends in this ZIP, and the row's `volume`/`units`/`avgLoanAmount` remain national totals. Canonical key (matches the response DTO); `zipCode` is an alias kept for cross-entity consistency with loans/sales. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank companies by it. There are two ways to get production for a geography: `POST /companies/{nmlsId}/markets` breaks ONE company's production out by market, and `POST /loans/analytics/chart` with `measure: \"volume\"`, `slice: \"loanCompany\"` and a geographic filter answers the reverse — the companies that actually produced in that geography, each with the volume they produced there."}]},"zipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zip`, identical behavior — the registered business address ZIP code, i.e. where the company is headquartered, NOT where it produced loans. The row's `volume`/`units`/`avgLoanAmount` remain national totals. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank companies by it. There are two ways to get production for a geography: `POST /companies/{nmlsId}/markets` breaks ONE company's production out by market, and `POST /loans/analytics/chart` with `measure: \"volume\"`, `slice: \"loanCompany\"` and a geographic filter answers the reverse — the companies that actually produced in that geography, each with the volume they produced there."}]}},"type":"object"},"footprint":{"anyOf":[{"$ref":"#/components/schemas/CompanyFootprintFilter"},{"items":{"$ref":"#/components/schemas/CompanyFootprintFilter"},"type":"array"}],"description":"Scoped lender filter(s). Each entry names ONE lender relationship and the metric bounds that must hold INSIDE it — `{lender:'<id>', volume:{gte:50000000}}` means '$50M funded by that lender', not '$50M somewhere and one loan with them'. Several entries AND together. Geographic market filters are not available on companies: that rollup is not written for these records, so use `POST /companies/{nmlsId}/markets` (live-aggregated) for a company's geography."},"lenderFilters":{"items":{"$ref":"#/components/schemas/LenderFilterEntry"},"type":"array"},"lenderMatchMode":{"$ref":"#/components/schemas/LenderMatchMode"},"locationBasis":{"description":"What the geographic filters (`city`/`state`/`zip`/`zipCode`/`geoPoint`) select. `registeredAddress` (the default) matches companies whose REGISTERED BUSINESS ADDRESS is in the place — a company registered elsewhere is excluded no matter how much it lends there. `production` matches companies that PRODUCED loans in the place, whatever address they are registered at, which is usually what a geographic search means. It changes only WHICH companies are returned: every non-geographic filter applies identically either way, `scopedVolume`/`scopedUnits` report in-geography production under both, and `countCompanies` honors this field, so a count and a list built from the same body always describe the same set. Measured on an 8-state Southeast search: under `registeredAddress` the largest actual producer in the region is absent at any depth, because it is registered in Michigan.","enum":["registeredAddress","production"],"type":"string"},"pagination":{"$ref":"#/components/schemas/Pagination"},"period":{"$ref":"#/components/schemas/Period"},"sort":{"items":{"properties":{"field":{"enum":["name","nmlsId","companyType","city","state","volume","units","scopedVolume","scopedUnits","teamSize","loCount","rosterJoined","rosterLeft","producersOnly"],"type":"string"},"order":{"$ref":"#/components/schemas/SortOrder"}},"required":["field"],"type":"object"},"type":"array"}},"type":"object"},"CompanyListResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/CompanySummary"},"type":"array"},"locationNormalizations":{"description":"How each location filter value resolved. Present when a `city`/`county`/`state`/`zip` filter was supplied.","items":{"$ref":"#/components/schemas/LocationNormalization"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"CompanyMarketBucket":{"properties":{"avgLoanAmount":{"nullable":true,"type":"number"},"key":{"description":"Join-stable bucket identity — ZIP `\"92683\"`, city `\"orlando|fl\"`, county 5-digit FIPS `\"06037\"`, state `\"CA\"`.","nullable":true,"type":"string"},"name":{"description":"Human label, in the same form the matching `/breakdowns` route publishes: a county reads `Middlesex County (MA)`, a state `MA`, a city `Belmont, MA` (this grain is a city within one state). `key` is the identity; `name` is the only field to display.","nullable":true,"type":"string"},"shareOfBook":{"description":"Share of the entity's whole period volume as pre-stored on the entity record, 0–100. Always null for a company: the pre-aggregated market rollups are not written for companies, so this figure is computed live and has no stored share to report. Use `shareOfScope`, or divide by `totals.volume`.","nullable":true,"type":"number"},"shareOfScope":{"description":"Share of the volume of every market RANKED at this grain, 0–100 — the denominator is the whole footprint the request selected, NOT the page. It therefore sums to 100 only when `limit` covers every bucket; on a shorter page the shortfall is the tail you did not ask for. (Note the scale: 0–100, unlike the Community Lending fractions, which are 0–1.)","nullable":true,"type":"number"},"units":{"nullable":true,"type":"number"},"volume":{"description":"Dollar volume in this market. A ranked top-N figure is a distributed approximation and can understate slightly (measured: 1.2% on one headline market); narrowing the request to this market with `zipCodes` returns the exact figure.","nullable":true,"type":"number"}},"required":["key","name","volume","units","avgLoanAmount","shareOfScope","shareOfBook"],"type":"object"},"CompanyMarketsCommunityLending":{"description":"The Community Lending mix of this footprint: the neighborhood characteristics of where the production landed, as percentages on a 0-100 scale. Null when nothing in scope resolved to a neighborhood — an absent block, never a row of zeroes, because 'no data' and '0%' are different answers. Read `basis` before comparing two responses. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"properties":{"affordableHousingTractPct":{"description":"Share of production, 0-100, in neighborhoods carrying an affordable-housing designation. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"basis":{"description":"Which measurement produced this block, and they are NOT the same number. `entityRollup` is the neighborhood mix of the entity's own production over the whole period — the default. `marketsInScope` is the neighborhood profile of the markets the request selected, weighted by the entity's production in each, and is what any ZIP, date or filter scope returns, because a whole-period rollup cannot be re-cut to a narrower question.","enum":["entityRollup","marketsInScope"],"type":"string"},"coveredProductionPct":{"description":"`marketsInScope` only — what share of the weighted production, 0-100, sits in a market that resolved to neighborhood data. Below 100 means the mix describes part of the footprint, not all of it.","nullable":true,"type":"number"},"difficultDevelopmentAreaPct":{"description":"Share of production, 0-100, in designated difficult development areas. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"distressedTractPct":{"description":"Share of production, 0-100, in distressed or underserved nonmetropolitan middle-income neighborhoods. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"floodHazardTractPct":{"description":"Share of production, 0-100, in neighborhoods inside a special flood hazard area. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"incomeLevelMix":{"description":"`marketsInScope` only — the full relative-income distribution of the neighborhoods, 0-100, summing to about 100. Null on `entityRollup`, which stores the predominant band but no distribution; publishing one derived from a single label would be a histogram nobody measured. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"properties":{"low":{"nullable":true,"type":"number"},"middle":{"nullable":true,"type":"number"},"moderate":{"nullable":true,"type":"number"},"upper":{"nullable":true,"type":"number"}},"required":["low","moderate","middle","upper"],"type":"object"},"loansWithCommunityData":{"description":"`entityRollup` only — how many of the entity's transactions in the period resolved to a neighborhood. This is the denominator every share below is a share OF, so read it first: a 100% share over three transactions is not a footprint.","nullable":true,"type":"number"},"lowModIncomeTractPct":{"description":"Share of production, 0-100, in low- or moderate-income neighborhoods. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"majorityMinorityTractPct":{"description":"Share of production, 0-100, in majority-minority neighborhoods. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"marketsInScope":{"description":"`marketsInScope` only — ZIP markets the mix considered, including any that carried no neighborhood data.","nullable":true,"type":"number"},"marketsWithCommunityData":{"description":"`marketsInScope` only — ZIP markets that resolved to neighborhood data.","nullable":true,"type":"number"},"opportunityZonePct":{"description":"Share of production, 0-100, in designated Opportunity Zones. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"predominantIncomeLevel":{"description":"The most common relative-income classification of the neighborhoods, on the standard four-band scale. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","enum":["low","moderate","middle","upper",null],"nullable":true,"type":"string"},"ruralTractPct":{"description":"Share of production, 0-100, in neighborhoods classified rural. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"usdaEligibleTractPct":{"description":"Share of production, 0-100, in neighborhoods eligible for USDA rural housing programs. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"}},"required":["basis","loansWithCommunityData","marketsWithCommunityData","marketsInScope","coveredProductionPct","predominantIncomeLevel","incomeLevelMix","lowModIncomeTractPct","majorityMinorityTractPct","ruralTractPct","opportunityZonePct","affordableHousingTractPct","distressedTractPct","usdaEligibleTractPct","floodHazardTractPct","difficultDevelopmentAreaPct"],"type":"object"},"CompanyMarketsDateRange":{"description":"Custom window, applied IN ADDITION to `period` (the two intersect). Use it for a window the named periods cannot express.","properties":{"from":{"description":"Inclusive lower bound, `YYYY-MM-DD` (a bare `YYYY` or `YYYY-MM` expands to the start of that period).","example":"2025-01-01","type":"string"},"to":{"description":"Inclusive upper bound, `YYYY-MM-DD` (a bare `YYYY` or `YYYY-MM` expands to the END of that period).","example":"2025-12-31","type":"string"}},"type":"object"},"CompanyMarketsRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"dateRange":{"$ref":"#/components/schemas/CompanyMarketsDateRange"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"borrowerStatus":{"$ref":"#/components/schemas/LoanBorrowerStatusFilterValue"},"broker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Broker shop NMLS id (digits only). A broker is a company — resolve a broker name to its NMLS id via instantSearch (or listCompanies)."}]},"buyerEntityType":{"$ref":"#/components/schemas/BooleanFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"conforming":{"$ref":"#/components/schemas/BooleanFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County name (e.g. \"Broward\") or 5-digit FIPS code. Names resolve to FIPS server-side; include a `state` filter to disambiguate."}]},"currentBalance":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated remaining principal balance (~19% populated). Approximate current equity as `homeValue` (AVM) minus this."}]},"employer":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Employer/company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Point-in-time equity recorded on the loan (sparse, ~10%). NOT a live current-equity figure. For HELOC/cash-out targeting on up-to-date equity, use properties search (listProperties) instead — its equity is far better populated and current."}]},"excludeBroker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans brokered by this broker-shop NMLS id (digits only) — the inverse of `broker`."}]},"excludeCity":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this city — the inverse of `city`."}]},"excludeLender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans from this lender ID (\"everyone but X\") — the inverse of `lender`, same id contract (resolve via instantSearch/listLenders). Loans with no lender stay in the results."}]},"excludeLoanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans funded by this company NMLS id (digits only) — the inverse of `loanCompany`."}]},"excludeOriginator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans with this originator NMLS id (digits only) — the inverse of `originator`. Common for 'everyone but my own shop' lists."}]},"excludeState":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this state (2-letter code, e.g. \"CA\") — the inverse of `state`. For \"everywhere but this state\" lists."}]},"excludeZipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this ZIP code — the inverse of `zipCode`."}]},"fips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exact 5-digit county FIPS code (no name resolution) — the code-only escape hatch alongside `county`."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"homeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"AVM (automated valuation) at the linked property (~26%, MLS-linked). Pair with `currentBalance` to approximate current equity."}]},"includeUnknownOriginator":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Include loans that have no originator NMLS id. Omitted/false (default): such loans are excluded — the vast majority are pre-2016 public records with no linkable originator. true: include them. Note that the default scopes results to loans with a known originator (~2016+ recordings)."}]},"interestRate":{"$ref":"#/components/schemas/NumericFilterValue"},"lender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender ID — the normalized lender-dictionary key, NOT a fuzzy name match. Resolve a lender via instantSearch (or listLenders) and pass the `id` it returns (e.g. \"mortgage_rocket\" or \"mortgage rocket\"). Underscores and letter case are normalized, so either id surface works. A stored normalized lender name (what the `slice: \"lender\"` chart buckets emit) is also accepted, so a chart bucket key filters directly. A value that is neither returns 400 rather than silently matching nothing — to search by lender NAME, use `lenderName`."}]},"lenderName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender name as recorded on the loan document — fuzzy, all-terms match (e.g. \"Fifth Third\"). The name counterpart to the exact-id `lender` filter; use `lender` when you have a resolved id, and this when you only have a name."}]},"loanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Funding/loan company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"loanType":{"$ref":"#/components/schemas/LoanTypeFilterValue"},"ltvAtOrigination":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan-to-value at ORIGINATION (sparse). This is not a current LTV — there is no stored current-LTV field on loans."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"mortgageDate":{"$ref":"#/components/schemas/DateFilterValue"},"originator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Loan originator NMLS id (digits only). To search by name use `originatorName`, or resolve a name to its id via instantSearch."}]},"originatorName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (same originator can return wildly different counts by name string). Resolve the loan officer via instantSearch and filter by `originator` (exact NMLS id) instead. Still functional for now."}]},"saleDate":{"$ref":"#/components/schemas/DateFilterValue"},"salePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"transactionType":{"$ref":"#/components/schemas/LoanTransactionTypeFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zipCode` — same ZIP filter, accepted for cross-entity key parity."}]},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"limit":{"description":"Buckets returned per grain (default 25). The summary is computed BEFORE this slice, so it describes the footprint and not the page.","maximum":200,"minimum":1,"type":"integer"},"period":{"allOf":[{"$ref":"#/components/schemas/Period"},{"description":"Named window over the company's recorded transactions (default `last12Months`)."}]},"zipCodes":{"description":"Narrow the footprint to these ZIP codes. Values are normalized to 5 digits, so a ZIP that lost its leading zero in a spreadsheet (`1001`) still resolves. A value that is not 1–5 digits returns 400 rather than being silently dropped.","example":["92683","92703"],"items":{"type":"string"},"maxItems":200,"type":"array"}},"type":"object"},"CompanyMarketsResponse":{"properties":{"nmlsId":{"type":"string"},"period":{"type":"string"},"rollups":{"properties":{"cities":{"items":{"$ref":"#/components/schemas/CompanyMarketBucket"},"type":"array"},"counties":{"items":{"$ref":"#/components/schemas/CompanyMarketBucket"},"type":"array"},"states":{"items":{"$ref":"#/components/schemas/CompanyMarketBucket"},"type":"array"}},"required":["cities","counties","states"],"type":"object"},"source":{"$ref":"#/components/schemas/CompanyMarketsSource"},"summary":{"$ref":"#/components/schemas/CompanyMarketsSummary"},"totals":{"description":"The whole matched book — every transaction the filters selected, including those that could not be placed in a market. The denominator for `summary.shareOfMatchedVolume`.","properties":{"avgLoanAmount":{"nullable":true,"type":"number"},"excluded":{"description":"Transactions held out of `volume` because their amount is an out-of-range fill rather than a real figure — the second kind of omission this response reports, alongside `summary.unresolved` (production that could not be placed in a market). Compare against `units` to see the share `volume` was computed over: a company whose amounts are mostly unreadable and one that is genuinely small are indistinguishable without it. Absent when the money column is unguarded.","nullable":true,"type":"number"},"units":{"nullable":true,"type":"number"},"volume":{"nullable":true,"type":"number"}},"required":["volume","units","avgLoanAmount"],"type":"object"},"zips":{"items":{"$ref":"#/components/schemas/CompanyMarketBucket"},"type":"array"}},"required":["nmlsId","period","source","summary","zips","rollups","totals"],"type":"object"},"CompanyMarketsSource":{"properties":{"mode":{"description":"Companies are always computed live from the recorded transactions — there is no pre-aggregated market rollup on a company record to read.","enum":["live"],"type":"string"},"reasons":{"description":"Why the live path was selected, in evaluation order (e.g. `coverage-empty`, `zip-scope`, `date-scope`).","items":{"type":"string"},"type":"array"}},"required":["mode","reasons"],"type":"object"},"CompanyMarketsSummary":{"properties":{"avgLoanAmount":{"description":"Units-weighted mean loan size — equal to `volume ÷ units`, NOT the unweighted mean of the per-market averages (which differs by several percent and flips sign with the bucket-size mix).","nullable":true,"type":"number"},"bucketCount":{"type":"number"},"communityLending":{"$ref":"#/components/schemas/CompanyMarketsCommunityLending"},"shareOfBook":{"description":"Always null for a company — see the same field on a bucket.","nullable":true,"type":"number"},"shareOfMatchedVolume":{"description":"What percent of `totals.volume` these ZIP buckets account for, 0–100. Below 100 whenever transactions could not be placed to a ZIP or fall outside the ranked depth — published so a partial sum is never mistaken for a total.","nullable":true,"type":"number"},"units":{"nullable":true,"type":"number"},"unresolved":{"description":"Production the source could not place in a market, held OUT of the blend and reported here rather than ranked alongside real markets.","properties":{"bucketCount":{"type":"number"},"units":{"nullable":true,"type":"number"},"volume":{"nullable":true,"type":"number"}},"required":["bucketCount","volume","units"],"type":"object"},"volume":{"nullable":true,"type":"number"}},"required":["bucketCount","volume","units","avgLoanAmount","shareOfBook","shareOfMatchedVolume","unresolved","communityLending"],"type":"object"},"CompanyRegistration":{"nullable":true,"properties":{"activeLoCount":{"nullable":true,"type":"number"},"branchCount":{"nullable":true,"type":"number"},"businessStructure":{"nullable":true,"type":"string"},"city":{"nullable":true,"type":"string"},"dateFormed":{"nullable":true,"type":"string"},"formedIn":{"nullable":true,"type":"string"},"licensedStates":{"items":{"type":"string"},"nullable":true,"type":"array"},"location":{"nullable":true,"properties":{"lat":{"type":"number"},"lon":{"type":"number"}},"required":["lat","lon"],"type":"object"},"postalCode":{"nullable":true,"type":"string"},"primaryFederalRegulator":{"nullable":true,"type":"string"},"registrationStatus":{"nullable":true,"type":"string"},"state":{"nullable":true,"type":"string"},"stockSymbol":{"nullable":true,"type":"string"},"street":{"nullable":true,"type":"string"},"tradeNames":{"items":{"type":"string"},"nullable":true,"type":"array"},"websites":{"items":{"type":"string"},"nullable":true,"type":"array"}},"type":"object"},"CompanySlice":{"enum":["transactionType","loanType","city","county","state","zip","lender"],"type":"string"},"CompanySponsoredIndividual":{"properties":{"activeLicenseCount":{"nullable":true,"type":"number"},"city":{"nullable":true,"type":"string"},"firstName":{"nullable":true,"type":"string"},"fullName":{"nullable":true,"type":"string"},"hasDisciplinaryAction":{"nullable":true,"type":"boolean"},"id":{"type":"string"},"isActive":{"nullable":true,"type":"boolean"},"isBranchManager":{"nullable":true,"type":"boolean"},"lastName":{"nullable":true,"type":"string"},"licensedStates":{"items":{"type":"string"},"nullable":true,"type":"array"},"nmlsId":{"nullable":true,"type":"string"},"sponsorships":{"nullable":true},"state":{"nullable":true,"type":"string"}},"required":["id"],"type":"object"},"CompanySponsoredIndividualsResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/CompanySponsoredIndividual"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"CompanySponsorshipMovementRequest":{"properties":{"dateFrom":{"description":"Window start (ISO date, default 12 mo ago)","type":"string"},"dateTo":{"description":"Window end (ISO date, default today)","type":"string"},"direction":{"default":"both","enum":["arrivals","departures","both"],"type":"string"},"size":{"default":25,"description":"Max individuals per direction","type":"number"}},"type":"object"},"CompanySponsorshipMovementResponse":{"properties":{"arrivalSources":{"items":{"properties":{"companyName":{"type":"string"},"companyNmlsId":{"nullable":true,"type":"string"},"count":{"type":"number"}},"required":["companyNmlsId","companyName","count"],"type":"object"},"type":"array"},"arrivals":{"items":{"properties":{"name":{"type":"string"},"nmlsId":{"type":"string"},"previousCompany":{"nullable":true,"type":"string"},"previousCompanyNmlsId":{"nullable":true,"type":"string"},"startDate":{"type":"string"}},"required":["nmlsId","name","startDate","previousCompany","previousCompanyNmlsId"],"type":"object"},"type":"array"},"departureDests":{"items":{"properties":{"companyName":{"type":"string"},"companyNmlsId":{"nullable":true,"type":"string"},"count":{"type":"number"}},"required":["companyNmlsId","companyName","count"],"type":"object"},"type":"array"},"departures":{"items":{"properties":{"endDate":{"type":"string"},"name":{"type":"string"},"nextCompany":{"nullable":true,"type":"string"},"nextCompanyNmlsId":{"nullable":true,"type":"string"},"nmlsId":{"type":"string"}},"required":["nmlsId","name","endDate","nextCompany","nextCompanyNmlsId"],"type":"object"},"type":"array"},"leftIndustry":{"type":"number"},"newToIndustry":{"type":"number"},"summary":{"properties":{"arrivals":{"type":"number"},"departures":{"type":"number"},"netChange":{"type":"number"}},"required":["arrivals","departures","netChange"],"type":"object"}},"required":["summary","arrivalSources","departureDests","newToIndustry","leftIndustry","arrivals","departures"],"type":"object"},"CompanySummary":{"properties":{"avgLoanAmount":{"description":"Mean loan size for the selected period, derived from the TOTAL `volume` and `units` across ALL markets — NOT scoped to any geographic filter (`city`/`state`/`zip`/`zipCode`/`geoPoint`) in this request. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank companies by it. There are two ways to get production for a geography: `POST /companies/{nmlsId}/markets` breaks ONE company's production out by market, and `POST /loans/analytics/chart` with `measure: \"volume\"`, `slice: \"loanCompany\"` and a geographic filter answers the reverse — the companies that actually produced in that geography, each with the volume they produced there.","nullable":true,"type":"number"},"city":{"nullable":true,"type":"string"},"companyType":{"nullable":true,"type":"string"},"id":{"description":"Document ID","type":"string"},"loCount":{"nullable":true,"type":"number"},"name":{"nullable":true,"type":"string"},"nmlsId":{"nullable":true,"type":"string"},"rosterJoined":{"description":"Loan officers who joined the company during the selected period — individuals whose sponsorship with the company began inside the window. IMPORTANT — this counts LICENSING EVENTS, not confirmed employer moves. A loan officer holds a separate license record for every state they are sponsored in, and this counts each individual whose sponsorship began or ended inside the window, so a single added or lapsed state license registers as an arrival or a departure even when the person's employment did not change. Measured on large lenders: 13-24% of a 12-month `rosterLeft` are still sponsored by the same employer today, and 33-50% of a 12-month `rosterJoined` were already sponsored by it before the window began. Treat both as directional indicators of movement, not as headcounts. `rosterJoined` and `rosterLeft` are measured from the same source on the same window basis, so unlike the retired `loLoss` — which had no arrivals figure computed the same way — the two can legitimately be combined into a churn rate. Both also grow with the window, so a longer period reports more than a shorter one and the periods are comparable in that direction.","nullable":true,"type":"number"},"rosterLeft":{"description":"Loan officers who left the company during the selected period — individuals whose sponsorship with the company ended inside the window. IMPORTANT — this counts LICENSING EVENTS, not confirmed employer moves. A loan officer holds a separate license record for every state they are sponsored in, and this counts each individual whose sponsorship began or ended inside the window, so a single added or lapsed state license registers as an arrival or a departure even when the person's employment did not change. Measured on large lenders: 13-24% of a 12-month `rosterLeft` are still sponsored by the same employer today, and 33-50% of a 12-month `rosterJoined` were already sponsored by it before the window began. Treat both as directional indicators of movement, not as headcounts. `rosterJoined` and `rosterLeft` are measured from the same source on the same window basis, so unlike the retired `loLoss` — which had no arrivals figure computed the same way — the two can legitimately be combined into a churn rate. Both also grow with the window, so a longer period reports more than a shorter one and the periods are comparable in that direction.","nullable":true,"type":"number"},"scopedUnits":{"description":"The company's loan count INSIDE the geography this request names, on the same basis as `scopedVolume`. Sortable. When the request names no geography — or names one only inside an `or` group or a negation — the scope is everywhere, and this is identical to the unscoped figure beside it. Reconciles with `POST /companies/{nmlsId}/markets` for the same geography and period: both are computed from the same recorded transactions and neither excludes transactions with no identified loan officer.","nullable":true,"type":"number"},"scopedVolume":{"description":"The company's dollar production INSIDE the geography this request names — what a `city`/`state`/`zip`/`zipCode`/`geoPoint` filter was almost certainly asking for, and what the sibling `volume` is not. Sort by `scopedVolume` to rank companies by it. When the request names no geography — or names one only inside an `or` group or a negation — the scope is everywhere, and this is identical to the unscoped figure beside it. Reconciles with `POST /companies/{nmlsId}/markets` for the same geography and period: both are computed from the same recorded transactions and neither excludes transactions with no identified loan officer.","nullable":true,"type":"number"},"state":{"nullable":true,"type":"string"},"teamSize":{"nullable":true,"type":"number"},"units":{"description":"The company's TOTAL loan count for the selected period across ALL markets — NOT scoped to any geographic filter (`city`/`state`/`zip`/`zipCode`/`geoPoint`) in this request, exactly as described on `volume`. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank companies by it. There are two ways to get production for a geography: `POST /companies/{nmlsId}/markets` breaks ONE company's production out by market, and `POST /loans/analytics/chart` with `measure: \"volume\"`, `slice: \"loanCompany\"` and a geographic filter answers the reverse — the companies that actually produced in that geography, each with the volume they produced there.","nullable":true,"type":"number"},"volume":{"description":"The company's TOTAL dollar production for the selected period across ALL markets — NOT scoped to any geographic filter (`city`/`state`/`zip`/`zipCode`/`geoPoint`) in this request. Those filters select WHICH companies are returned, by registered business address, and never change WHAT is summed here. Since the list sorts by `volume` descending by default, a geo-filtered search ranks companies by NATIONAL production, so the top row can be many times larger than that company's production inside the filtered area. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank companies by it. There are two ways to get production for a geography: `POST /companies/{nmlsId}/markets` breaks ONE company's production out by market, and `POST /loans/analytics/chart` with `measure: \"volume\"`, `slice: \"loanCompany\"` and a geographic filter answers the reverse — the companies that actually produced in that geography, each with the volume they produced there.","nullable":true,"type":"number"},"zip":{"nullable":true,"type":"string"}},"required":["id"],"type":"object"},"CompanySummaryRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"borrowerStatus":{"$ref":"#/components/schemas/LoanBorrowerStatusFilterValue"},"broker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Broker shop NMLS id (digits only). A broker is a company — resolve a broker name to its NMLS id via instantSearch (or listCompanies)."}]},"buyerEntityType":{"$ref":"#/components/schemas/BooleanFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"conforming":{"$ref":"#/components/schemas/BooleanFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County name (e.g. \"Broward\") or 5-digit FIPS code. Names resolve to FIPS server-side; include a `state` filter to disambiguate."}]},"currentBalance":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated remaining principal balance (~19% populated). Approximate current equity as `homeValue` (AVM) minus this."}]},"employer":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Employer/company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Point-in-time equity recorded on the loan (sparse, ~10%). NOT a live current-equity figure. For HELOC/cash-out targeting on up-to-date equity, use properties search (listProperties) instead — its equity is far better populated and current."}]},"excludeBroker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans brokered by this broker-shop NMLS id (digits only) — the inverse of `broker`."}]},"excludeCity":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this city — the inverse of `city`."}]},"excludeLender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans from this lender ID (\"everyone but X\") — the inverse of `lender`, same id contract (resolve via instantSearch/listLenders). Loans with no lender stay in the results."}]},"excludeLoanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans funded by this company NMLS id (digits only) — the inverse of `loanCompany`."}]},"excludeOriginator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans with this originator NMLS id (digits only) — the inverse of `originator`. Common for 'everyone but my own shop' lists."}]},"excludeState":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this state (2-letter code, e.g. \"CA\") — the inverse of `state`. For \"everywhere but this state\" lists."}]},"excludeZipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this ZIP code — the inverse of `zipCode`."}]},"fips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exact 5-digit county FIPS code (no name resolution) — the code-only escape hatch alongside `county`."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"homeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"AVM (automated valuation) at the linked property (~26%, MLS-linked). Pair with `currentBalance` to approximate current equity."}]},"includeUnknownOriginator":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Include loans that have no originator NMLS id. Omitted/false (default): such loans are excluded — the vast majority are pre-2016 public records with no linkable originator. true: include them. Note that the default scopes results to loans with a known originator (~2016+ recordings)."}]},"interestRate":{"$ref":"#/components/schemas/NumericFilterValue"},"lender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender ID — the normalized lender-dictionary key, NOT a fuzzy name match. Resolve a lender via instantSearch (or listLenders) and pass the `id` it returns (e.g. \"mortgage_rocket\" or \"mortgage rocket\"). Underscores and letter case are normalized, so either id surface works. A stored normalized lender name (what the `slice: \"lender\"` chart buckets emit) is also accepted, so a chart bucket key filters directly. A value that is neither returns 400 rather than silently matching nothing — to search by lender NAME, use `lenderName`."}]},"lenderName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender name as recorded on the loan document — fuzzy, all-terms match (e.g. \"Fifth Third\"). The name counterpart to the exact-id `lender` filter; use `lender` when you have a resolved id, and this when you only have a name."}]},"loanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Funding/loan company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"loanType":{"$ref":"#/components/schemas/LoanTypeFilterValue"},"ltvAtOrigination":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan-to-value at ORIGINATION (sparse). This is not a current LTV — there is no stored current-LTV field on loans."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"mortgageDate":{"$ref":"#/components/schemas/DateFilterValue"},"originator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Loan originator NMLS id (digits only). To search by name use `originatorName`, or resolve a name to its id via instantSearch."}]},"originatorName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (same originator can return wildly different counts by name string). Resolve the loan officer via instantSearch and filter by `originator` (exact NMLS id) instead. Still functional for now."}]},"saleDate":{"$ref":"#/components/schemas/DateFilterValue"},"salePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"transactionType":{"$ref":"#/components/schemas/LoanTransactionTypeFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zipCode` — same ZIP filter, accepted for cross-entity key parity."}]},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"nmlsId":{"type":"string"},"nmlsIds":{"items":{"type":"string"},"type":"array"},"period":{"$ref":"#/components/schemas/Period"}},"type":"object"},"CompanyTimeSeriesRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"borrowerStatus":{"$ref":"#/components/schemas/LoanBorrowerStatusFilterValue"},"broker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Broker shop NMLS id (digits only). A broker is a company — resolve a broker name to its NMLS id via instantSearch (or listCompanies)."}]},"buyerEntityType":{"$ref":"#/components/schemas/BooleanFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"conforming":{"$ref":"#/components/schemas/BooleanFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County name (e.g. \"Broward\") or 5-digit FIPS code. Names resolve to FIPS server-side; include a `state` filter to disambiguate."}]},"currentBalance":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated remaining principal balance (~19% populated). Approximate current equity as `homeValue` (AVM) minus this."}]},"employer":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Employer/company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Point-in-time equity recorded on the loan (sparse, ~10%). NOT a live current-equity figure. For HELOC/cash-out targeting on up-to-date equity, use properties search (listProperties) instead — its equity is far better populated and current."}]},"excludeBroker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans brokered by this broker-shop NMLS id (digits only) — the inverse of `broker`."}]},"excludeCity":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this city — the inverse of `city`."}]},"excludeLender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans from this lender ID (\"everyone but X\") — the inverse of `lender`, same id contract (resolve via instantSearch/listLenders). Loans with no lender stay in the results."}]},"excludeLoanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans funded by this company NMLS id (digits only) — the inverse of `loanCompany`."}]},"excludeOriginator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans with this originator NMLS id (digits only) — the inverse of `originator`. Common for 'everyone but my own shop' lists."}]},"excludeState":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this state (2-letter code, e.g. \"CA\") — the inverse of `state`. For \"everywhere but this state\" lists."}]},"excludeZipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this ZIP code — the inverse of `zipCode`."}]},"fips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exact 5-digit county FIPS code (no name resolution) — the code-only escape hatch alongside `county`."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"homeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"AVM (automated valuation) at the linked property (~26%, MLS-linked). Pair with `currentBalance` to approximate current equity."}]},"includeUnknownOriginator":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Include loans that have no originator NMLS id. Omitted/false (default): such loans are excluded — the vast majority are pre-2016 public records with no linkable originator. true: include them. Note that the default scopes results to loans with a known originator (~2016+ recordings)."}]},"interestRate":{"$ref":"#/components/schemas/NumericFilterValue"},"lender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender ID — the normalized lender-dictionary key, NOT a fuzzy name match. Resolve a lender via instantSearch (or listLenders) and pass the `id` it returns (e.g. \"mortgage_rocket\" or \"mortgage rocket\"). Underscores and letter case are normalized, so either id surface works. A stored normalized lender name (what the `slice: \"lender\"` chart buckets emit) is also accepted, so a chart bucket key filters directly. A value that is neither returns 400 rather than silently matching nothing — to search by lender NAME, use `lenderName`."}]},"lenderName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender name as recorded on the loan document — fuzzy, all-terms match (e.g. \"Fifth Third\"). The name counterpart to the exact-id `lender` filter; use `lender` when you have a resolved id, and this when you only have a name."}]},"loanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Funding/loan company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"loanType":{"$ref":"#/components/schemas/LoanTypeFilterValue"},"ltvAtOrigination":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan-to-value at ORIGINATION (sparse). This is not a current LTV — there is no stored current-LTV field on loans."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"mortgageDate":{"$ref":"#/components/schemas/DateFilterValue"},"originator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Loan originator NMLS id (digits only). To search by name use `originatorName`, or resolve a name to its id via instantSearch."}]},"originatorName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (same originator can return wildly different counts by name string). Resolve the loan officer via instantSearch and filter by `originator` (exact NMLS id) instead. Still functional for now."}]},"saleDate":{"$ref":"#/components/schemas/DateFilterValue"},"salePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"transactionType":{"$ref":"#/components/schemas/LoanTransactionTypeFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zipCode` — same ZIP filter, accepted for cross-entity key parity."}]},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"interval":{"$ref":"#/components/schemas/Interval"},"measure":{"$ref":"#/components/schemas/Measure"},"nmlsId":{"type":"string"},"nmlsIds":{"items":{"type":"string"},"type":"array"},"period":{"$ref":"#/components/schemas/Period"},"segment":{"$ref":"#/components/schemas/CompanySlice"}},"type":"object"},"CompanyTypeFilterValue":{"anyOf":[{"description":"One of (case-insensitive): BANK, CU, OTHER","enum":["BANK","CU","OTHER"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): BANK, CU, OTHER","enum":["BANK","CU","OTHER"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"ContactCardType":{"enum":["lo","agent","cobranded",null],"nullable":true,"type":"string"},"CountResponse":{"properties":{"lenderNormalizations":{"description":"How each `lenderName` value resolved against the lender dictionary. Present when a `lenderName` filter was supplied.","items":{"$ref":"#/components/schemas/LenderNormalization"},"type":"array"},"locationNormalizations":{"description":"How each location filter value resolved. Present when a `city`/`county`/`state`/`zip` filter was supplied.","items":{"$ref":"#/components/schemas/LocationNormalization"},"type":"array"},"total":{"description":"Exact count of records matching the filters","example":48213,"minimum":0,"type":"integer"}},"required":["total"],"type":"object"},"CrmActiveCall":{"nullable":true,"properties":{"entityId":{"type":"string"},"id":{"type":"string"},"organizationId":{"type":"string"},"recordName":{"nullable":true,"type":"string"},"toNumber":{"type":"string"}},"required":["id","organizationId","entityId","toNumber","recordName"],"type":"object"},"CrmActiveCallResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmActiveCall"}},"required":["data"],"type":"object"},"CrmActivityEntry":{"properties":{"actorEmail":{"nullable":true,"type":"string"},"actorImage":{"nullable":true,"type":"string"},"actorName":{"nullable":true,"type":"string"},"actorUserId":{"nullable":true,"type":"string"},"body":{"nullable":true,"type":"string"},"bodyHtml":{"nullable":true,"type":"string"},"createdAt":{"type":"number"},"data":{"nullable":true},"editedAt":{"nullable":true,"type":"number"},"id":{"type":"string"},"kind":{"$ref":"#/components/schemas/CrmActivityKind"},"linkedNotes":{"items":{"$ref":"#/components/schemas/CrmActivityEntry"},"type":"array"},"parentId":{"nullable":true,"type":"string"},"replies":{"items":{"$ref":"#/components/schemas/CrmActivityEntry"},"type":"array"},"replyCount":{"type":"number"},"subtype":{"type":"string"}},"required":["id","kind","subtype","body","bodyHtml","parentId","actorUserId","actorName","actorEmail","actorImage","createdAt","editedAt"],"type":"object"},"CrmActivityKind":{"enum":["note","system","automated"],"type":"string"},"CrmActivityList":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CrmActivityEntry"},"type":"array"}},"required":["data"],"type":"object"},"CrmAddContactResult":{"properties":{"data":{"properties":{"id":{"type":"string"}},"required":["id"],"type":"object"}},"required":["data"],"type":"object"},"CrmAddListMemberResult":{"properties":{"data":{"properties":{"added":{"type":"boolean"},"member":{"$ref":"#/components/schemas/CrmListMember"}},"required":["added","member"],"type":"object"}},"required":["data"],"type":"object"},"CrmAddMembersBulkResult":{"properties":{"data":{"properties":{"added":{"type":"number"},"addedEntityIds":{"items":{"type":"string"},"type":"array"},"createdEntityIds":{"items":{"type":"string"},"type":"array"},"enrichJobId":{"type":"string"},"total":{"type":"number"}},"required":["added","total","addedEntityIds","createdEntityIds"],"type":"object"}},"required":["data"],"type":"object"},"CrmAddNoteResult":{"properties":{"data":{"properties":{"id":{"type":"string"},"parentId":{"nullable":true,"type":"string"}},"required":["id","parentId"],"type":"object"}},"required":["data"],"type":"object"},"CrmAddRecordResult":{"properties":{"data":{"properties":{"added":{"type":"boolean"},"member":{"$ref":"#/components/schemas/CrmListMember"}},"required":["added","member"],"type":"object"}},"required":["data"],"type":"object"},"CrmAddRecordsBulkResult":{"properties":{"data":{"properties":{"added":{"type":"number"},"addedEntityIds":{"items":{"type":"string"},"type":"array"},"enrichJobId":{"type":"string"},"total":{"type":"number"}},"required":["added","total","addedEntityIds"],"type":"object"}},"required":["data"],"type":"object"},"CrmApplyMiUpdatesResult":{"properties":{"data":{"properties":{"applied":{"type":"number"}},"required":["applied"],"type":"object"}},"required":["data"],"type":"object"},"CrmApplyTemplateBody":{"properties":{"libraryTemplateId":{"type":"string"},"templateId":{"type":"string"}},"type":"object"},"CrmApplyTemplateResult":{"properties":{"data":{"properties":{"applied":{"items":{"$ref":"#/components/schemas/CrmCustomField"},"type":"array"},"objectTypeMismatch":{"type":"boolean"},"skipped":{"items":{"type":"string"},"type":"array"}},"required":["applied","skipped"],"type":"object"}},"required":["data"],"type":"object"},"CrmCall":{"properties":{"aiActions":{"items":{"$ref":"#/components/schemas/CrmCallAiAction"},"nullable":true,"type":"array"},"aiAnalyzedAt":{"nullable":true,"type":"number"},"aiLabel":{"nullable":true,"type":"string"},"aiSentiment":{"enum":["positive","neutral","negative",null],"nullable":true,"type":"string"},"aiSummary":{"nullable":true,"type":"string"},"answeredBy":{"enum":["human","machine","fax","unknown",null],"nullable":true,"type":"string"},"createdAt":{"type":"number"},"durationSeconds":{"nullable":true,"type":"number"},"endedAt":{"nullable":true,"type":"number"},"endedBy":{"enum":["caller","remote","system",null],"nullable":true,"type":"string"},"entityId":{"type":"string"},"fromNumber":{"type":"string"},"id":{"type":"string"},"organizationId":{"type":"string"},"recordingEnabled":{"type":"boolean"},"recordingSid":{"nullable":true,"type":"string"},"startedAt":{"nullable":true,"type":"number"},"status":{"type":"string"},"toNumber":{"type":"string"},"transcript":{"items":{"$ref":"#/components/schemas/CrmTranscriptSentence"},"nullable":true,"type":"array"},"transcriptSid":{"nullable":true,"type":"string"},"transcriptStatus":{"enum":["pending","processing","completed","failed","absent",null],"nullable":true,"type":"string"},"twilioCallSid":{"nullable":true,"type":"string"},"userId":{"type":"string"}},"required":["id","organizationId","entityId","userId","toNumber","fromNumber","twilioCallSid","status","durationSeconds","startedAt","endedAt","endedBy","answeredBy","recordingEnabled","recordingSid","transcriptSid","transcriptStatus","transcript","aiLabel","aiSummary","aiSentiment","aiActions","aiAnalyzedAt","createdAt"],"type":"object"},"CrmCallAiAction":{"properties":{"dueInDays":{"type":"number"},"durationMinutes":{"type":"number"},"startInDays":{"type":"number"},"title":{"type":"string"},"type":{"enum":["task","meeting"],"type":"string"}},"required":["type","title"],"type":"object"},"CrmCallAnalysisResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmCall"}},"required":["data"],"type":"object"},"CrmCallAnalyzeResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmCall"}},"required":["data"],"type":"object"},"CrmCallTranscriptResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmCall"}},"required":["data"],"type":"object"},"CrmCallerId":{"properties":{"createdAt":{"type":"number"},"friendlyName":{"nullable":true,"type":"string"},"id":{"type":"string"},"isDefault":{"type":"boolean"},"phoneNumber":{"type":"string"},"status":{"enum":["pending","verified","failed"],"type":"string"}},"required":["id","phoneNumber","friendlyName","status","isDefault","createdAt"],"type":"object"},"CrmCallerIdActionResult":{"properties":{"data":{"properties":{"callerId":{"allOf":[{"$ref":"#/components/schemas/CrmCallerId"},{"nullable":true}]},"validationCode":{"nullable":true,"type":"string"}},"required":["callerId"],"type":"object"}},"required":["data"],"type":"object"},"CrmCallerIdList":{"properties":{"data":{"properties":{"callerIds":{"items":{"$ref":"#/components/schemas/CrmCallerId"},"type":"array"},"configured":{"type":"boolean"}},"required":["callerIds","configured"],"type":"object"}},"required":["data"],"type":"object"},"CrmContactKind":{"enum":["phone","email","social","address","website","facebook","linkedin","x","zillow","realtor","youtube","instagram"],"type":"string"},"CrmContactSeed":{"properties":{"isPrimary":{"type":"boolean"},"kind":{"enum":["phone","email","social","address","website","facebook","linkedin","x","zillow","realtor","youtube","instagram"],"type":"string"},"label":{"nullable":true,"type":"string"},"value":{"nullable":true}},"required":["kind"],"type":"object"},"CrmCreateListFieldResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmCustomField"}},"required":["data"],"type":"object"},"CrmCreateRecordResult":{"properties":{"data":{"properties":{"created":{"type":"boolean"}},"required":["created"],"type":"object"}},"required":["data"],"type":"object"},"CrmCreateTemplateResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmTemplateWithFields"}},"required":["data"],"type":"object"},"CrmCustomField":{"properties":{"config":{"additionalProperties":{"nullable":true},"nullable":true,"type":"object"},"id":{"type":"string"},"key":{"type":"string"},"label":{"type":"string"},"listId":{"nullable":true,"type":"string"},"objectType":{"$ref":"#/components/schemas/CrmObjectType"},"options":{"items":{"$ref":"#/components/schemas/CrmCustomFieldOption"},"nullable":true,"type":"array"},"scope":{"enum":["object","list"],"type":"string"},"sortOrder":{"type":"number"},"type":{"$ref":"#/components/schemas/CrmCustomFieldType"}},"required":["id","scope","objectType","listId","key","label","type","options","config","sortOrder"],"type":"object"},"CrmCustomFieldList":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CrmCustomField"},"type":"array"}},"required":["data"],"type":"object"},"CrmCustomFieldOption":{"properties":{"color":{"type":"string"},"id":{"type":"string"},"label":{"type":"string"}},"required":["id","label"],"type":"object"},"CrmCustomFieldType":{"enum":["text","number","currency","date","select","multiselect","url","rating","checkbox","status","tags"],"type":"string"},"CrmCustomValue":{"properties":{"bool":{"nullable":true,"type":"boolean"},"date":{"minimum":0,"nullable":true,"type":"integer"},"multi":{"items":{"type":"string"},"nullable":true,"type":"array"},"num":{"nullable":true,"type":"number"},"text":{"nullable":true,"type":"string"}},"type":"object"},"CrmCustomValueResult":{"properties":{"data":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/CrmCustomValue"},"type":"object"},{"additionalProperties":{"additionalProperties":{"$ref":"#/components/schemas/CrmCustomValue"},"type":"object"},"type":"object"}]}},"required":["data"],"type":"object"},"CrmDeleteCallerIdResult":{"properties":{"data":{"properties":{"deleted":{"type":"boolean"}},"required":["deleted"],"type":"object"}},"required":["data"],"type":"object"},"CrmDeleteListFieldResult":{"properties":{"data":{"properties":{"deleted":{"type":"boolean"}},"required":["deleted"],"type":"object"}},"required":["data"],"type":"object"},"CrmDeleteNoteResult":{"properties":{"data":{"properties":{"deleted":{"type":"boolean"}},"required":["deleted"],"type":"object"}},"required":["data"],"type":"object"},"CrmDeleteRecordResult":{"properties":{"data":{"properties":{"removed":{"type":"boolean"}},"required":["removed"],"type":"object"}},"required":["data"],"type":"object"},"CrmDeleteRecordsResult":{"properties":{"data":{"properties":{"removed":{"items":{"type":"string"},"type":"array"},"skipped":{"items":{"type":"string"},"type":"array"}},"required":["removed","skipped"],"type":"object"}},"required":["data"],"type":"object"},"CrmDeleteTemplateResult":{"properties":{"data":{"properties":{"deleted":{"type":"boolean"}},"required":["deleted"],"type":"object"}},"required":["data"],"type":"object"},"CrmDerivedLocation":{"properties":{"cbsaCode":{"type":"string"},"county":{"type":"string"},"countyFips":{"type":"string"}},"type":"object"},"CrmDescribeOnAddResult":{"properties":{"data":{"properties":{"needsDescriptionEntityIds":{"items":{"type":"string"},"type":"array"}},"required":["needsDescriptionEntityIds"],"type":"object"}},"required":["data"],"type":"object"},"CrmDismissMiUpdatesResult":{"properties":{"data":{"properties":{"dismissed":{"type":"boolean"}},"required":["dismissed"],"type":"object"}},"required":["data"],"type":"object"},"CrmDisplay":{"properties":{"branchName":{"type":"string"},"branchNmlsId":{"type":"string"},"cbsaCode":{"type":"string"},"city":{"type":"string"},"companyName":{"type":"string"},"companyNmlsId":{"type":"string"},"county":{"type":"string"},"countyFips":{"type":"string"},"location":{"type":"string"},"name":{"type":"string"},"state":{"type":"string"},"subtitle":{"type":"string"},"units":{"type":"number"},"volume":{"type":"number"},"zip":{"type":"string"}},"required":["name"],"type":"object"},"CrmEditNoteResult":{"properties":{"data":{"properties":{"entityId":{"nullable":true,"type":"string"},"previousBodyHtml":{"nullable":true,"type":"string"},"updated":{"type":"boolean"}},"required":["updated","entityId","previousBodyHtml"],"type":"object"}},"required":["data"],"type":"object"},"CrmEmailAttachment":{"properties":{"base64":{"type":"string"},"filename":{"type":"string"},"mimeType":{"type":"string"}},"required":["filename","mimeType","base64"],"type":"object"},"CrmEmailRecipient":{"properties":{"email":{"type":"string"},"entityId":{"type":"string"},"isPrimary":{"type":"boolean"},"label":{"nullable":true,"type":"string"},"name":{"type":"string"}},"required":["entityId","name","email","label","isPrimary"],"type":"object"},"CrmEmailRecipientArray":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CrmEmailRecipient"},"type":"array"}},"required":["data"],"type":"object"},"CrmEmailSendBody":{"properties":{"attachments":{"items":{"$ref":"#/components/schemas/CrmEmailAttachment"},"type":"array"},"bcc":{"items":{"type":"string"},"type":"array"},"cc":{"items":{"type":"string"},"type":"array"},"entityId":{"type":"string"},"html":{"type":"string"},"organizationId":{"type":"string"},"provider":{"$ref":"#/components/schemas/CrmMailProvider"},"subject":{"type":"string"},"text":{"type":"string"},"to":{"items":{"type":"string"},"minItems":1,"type":"array"}},"required":["entityId","to","subject","html","text"],"type":"object"},"CrmEmailSendResult":{"properties":{"provider":{"$ref":"#/components/schemas/CrmMailProvider"},"result":{"enum":["sent","needs-connect"],"type":"string"}},"required":["result","provider"],"type":"object"},"CrmEmailUpstreamError":{"properties":{"detail":{"type":"string"},"result":{"enum":["error"],"type":"string"},"status":{"type":"number"}},"required":["result","status","detail"],"type":"object"},"CrmEnrichmentContact":{"properties":{"isPrimary":{"type":"boolean"},"kind":{"$ref":"#/components/schemas/CrmContactKind"},"label":{"nullable":true,"type":"string"},"value":{"nullable":true}},"required":["kind"],"type":"object"},"CrmEnrichmentOverrideSources":{"description":"Origin of each `overrides` value: \"mm\" (ours) or \"imported\" (the customer's). An \"mm\" value the record already renders from the mirror is NOT pinned, so the record keeps tracking. Omit to pin everything.","properties":{"company":{"type":"string"},"companyType":{"type":"string"},"title":{"type":"string"}},"type":"object"},"CrmEnrichmentOverrides":{"properties":{"company":{"type":"string"},"companyType":{"type":"string"},"title":{"type":"string"}},"type":"object"},"CrmEnrichmentResult":{"properties":{"data":{"properties":{"linked":{"type":"boolean"},"seeded":{"type":"number"}},"required":["linked","seeded"],"type":"object"}},"required":["data"],"type":"object"},"CrmEntityType":{"enum":["lo","agent","company","branch"],"type":"string"},"CrmFilterMembersResult":{"properties":{"data":{"properties":{"entityIds":{"items":{"type":"string"},"type":"array"}},"required":["entityIds"],"type":"object"}},"required":["data"],"type":"object"},"CrmGenerateDescriptionResult":{"properties":{"data":{"properties":{"description":{"nullable":true,"type":"string"}},"required":["description"],"type":"object"}},"required":["data"],"type":"object"},"CrmGrantListAccessResult":{"properties":{"data":{"properties":{"granted":{"type":"boolean"}},"required":["granted"],"type":"object"}},"required":["data"],"type":"object"},"CrmGrantRecordAccessRequestResult":{"properties":{"data":{"properties":{"granted":{"type":"boolean"},"status":{"enum":["granted"],"type":"string"}},"required":["granted","status"],"type":"object"}},"required":["data"],"type":"object"},"CrmGrantRecordAccessResult":{"properties":{"data":{"properties":{"granted":{"type":"boolean"}},"required":["granted"],"type":"object"}},"required":["data"],"type":"object"},"CrmHangupCallResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmCall"}},"required":["data"],"type":"object"},"CrmImportAccepted":{"properties":{"data":{"properties":{"jobId":{"description":"Poll GET /crm/import/{jobId} for progress + per-row errors.","type":"string"}},"required":["jobId"],"type":"object"}},"required":["data"],"type":"object"},"CrmImportErrorCode":{"description":"Failure reason on a failed row; drives friendly client copy. Absent on success.","enum":["MISSING_NAME","RECORD_NOT_FOUND","WRONG_OBJECT_TYPE","NO_ACCESS","UNKNOWN_FIELD","INVALID","INTERNAL"],"type":"string"},"CrmImportJob":{"properties":{"data":{"properties":{"completedAt":{"type":"string"},"error":{"type":"string"},"errorsUrl":{"type":"string"},"failed":{"type":"number"},"jobId":{"type":"string"},"resultsUrl":{"type":"string"},"startedAt":{"type":"string"},"status":{"enum":["queued","running","completed","failed"],"type":"string"},"succeeded":{"type":"number"},"total":{"type":"number"}},"required":["jobId","status","total","succeeded","failed"],"type":"object"}},"required":["data"],"type":"object"},"CrmImportPhone":{"properties":{"e164":{"type":"string"},"raw":{"type":"string"}},"required":["raw","e164"],"type":"object"},"CrmImportResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmImportSummary"}},"required":["data"],"type":"object"},"CrmImportRow":{"properties":{"address":{"type":"string"},"city":{"type":"string"},"company":{"description":"Employer override for people rows; ignored on companies imports.","type":"string"},"county":{"type":"string"},"countyFips":{"type":"string"},"customValues":{"additionalProperties":{"$ref":"#/components/schemas/CrmCustomValue"},"type":"object"},"email":{"type":"string"},"emails":{"description":"Additional emails in submitted order (first non-duplicate becomes primary via oldest-wins).","items":{"type":"string"},"maxItems":5,"type":"array"},"entityId":{"description":"Set to update an existing record; omit to create one.","type":"string"},"facebook":{"type":"string"},"instagram":{"type":"string"},"link":{"allOf":[{"$ref":"#/components/schemas/CrmLink"},{"description":"Match pointer; an MM-sourced link populates the entity mirror."}]},"linkedin":{"type":"string"},"location":{"type":"string"},"name":{"type":"string"},"note":{"description":"Plain-text timeline note appended to the record's activity feed, authored by the importing user. Distinct from `notes` (the Description scalar).","maxLength":2000,"type":"string"},"notes":{"type":"string"},"ownerUserId":{"description":"Working owner (member userId) for this CREATED record; overrides the batch-level ownerUserId. Ignored on update rows (entityId set) — import never reassigns an existing record's owner. Assigning any owner other than the caller requires an org admin.","type":"string"},"phone":{"$ref":"#/components/schemas/CrmImportPhone"},"phones":{"description":"Additional phones in submitted order.","items":{"$ref":"#/components/schemas/CrmImportPhone"},"maxItems":5,"type":"array"},"realtor":{"type":"string"},"state":{"type":"string"},"status":{"type":"string"},"subtitle":{"type":"string"},"title":{"description":"Role title override for people rows (the record's Title field, column and filter) — distinct from `subtitle`, the display line under the name. Trimmed; blank reads as absent. Overwrites on update rows. Ignored on companies imports.","type":"string"},"website":{"type":"string"},"x":{"type":"string"},"youtube":{"type":"string"},"zillow":{"type":"string"},"zip":{"type":"string"}},"type":"object"},"CrmImportRowResult":{"properties":{"code":{"$ref":"#/components/schemas/CrmImportErrorCode"},"entityId":{"type":"string"},"error":{"type":"string"},"outcome":{"enum":["created","updated","failed"],"type":"string"},"row":{"type":"number"}},"required":["row","outcome"],"type":"object"},"CrmImportSummary":{"properties":{"created":{"type":"number"},"enrichJobId":{"type":"string"},"failed":{"type":"number"},"results":{"items":{"$ref":"#/components/schemas/CrmImportRowResult"},"type":"array"},"total":{"type":"number"},"updated":{"type":"number"}},"required":["total","created","updated","failed","results"],"type":"object"},"CrmLenderChannels":{"properties":{"data":{"properties":{"byLo":{"additionalProperties":{"properties":{"channel":{"enum":["Bank","Credit Union","Broker","Retail","Unknown"],"type":"string"},"companyName":{"type":"string"},"companyNmlsId":{"type":"string"}},"required":["companyNmlsId","companyName","channel"],"type":"object"},"type":"object"}},"required":["byLo"],"type":"object"}},"required":["data"],"type":"object"},"CrmLink":{"properties":{"entityId":{"type":"string"},"mmaId":{"type":"string"},"nmlsId":{"type":"string"},"propertyId":{"type":"string"},"source":{"enum":["mm","manual"],"type":"string"}},"required":["source","entityId"],"type":"object"},"CrmLinkRecordResult":{"properties":{"data":{"properties":{"linked":{"type":"boolean"}},"required":["linked"],"type":"object"}},"required":["data"],"type":"object"},"CrmList":{"properties":{"canManage":{"type":"boolean"},"createdAt":{"type":"number"},"hasMember":{"type":"boolean"},"id":{"type":"string"},"memberCount":{"type":"number"},"name":{"type":"string"},"objectType":{"$ref":"#/components/schemas/CrmObjectType"},"visibility":{"enum":["private","organization","shared"],"type":"string"}},"required":["id","name","objectType","visibility","memberCount","createdAt"],"type":"object"},"CrmListArray":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CrmList"},"type":"array"}},"required":["data"],"type":"object"},"CrmListAssignee":{"properties":{"email":{"nullable":true,"type":"string"},"image":{"nullable":true,"type":"string"},"name":{"nullable":true,"type":"string"},"userId":{"type":"string"}},"required":["userId","name","email","image"],"type":"object"},"CrmListAssigneeList":{"properties":{"data":{"properties":{"assignees":{"items":{"$ref":"#/components/schemas/CrmListAssignee"},"type":"array"}},"required":["assignees"],"type":"object"}},"required":["data"],"type":"object"},"CrmListCreateResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmList"}},"required":["data"],"type":"object"},"CrmListDeleteResult":{"properties":{"data":{"properties":{"ok":{"type":"boolean"}},"required":["ok"],"type":"object"}},"required":["data"],"type":"object"},"CrmListFieldsResult":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CrmCustomField"},"type":"array"}},"required":["data"],"type":"object"},"CrmListMember":{"nullable":true,"properties":{"addedAt":{"type":"number"},"display":{"$ref":"#/components/schemas/CrmDisplay"},"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"lastActivityAt":{"nullable":true,"type":"number"},"overrides":{"$ref":"#/components/schemas/CrmOverlay"},"ownerUserId":{"nullable":true,"type":"string"}},"required":["entityId","entityType","addedAt","display"],"type":"object"},"CrmListMembershipEntry":{"properties":{"canManage":{"type":"boolean"},"id":{"type":"string"},"name":{"type":"string"},"objectType":{"$ref":"#/components/schemas/CrmObjectType"}},"required":["id","name","objectType","canManage"],"type":"object"},"CrmListMemberships":{"properties":{"memberships":{"additionalProperties":{"items":{"$ref":"#/components/schemas/CrmListMembershipEntry"},"type":"array"},"type":"object"}},"required":["memberships"],"type":"object"},"CrmListMembershipsResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmListMemberships"}},"required":["data"],"type":"object"},"CrmListShare":{"properties":{"createdAt":{"type":"number"},"email":{"nullable":true,"type":"string"},"id":{"type":"string"},"image":{"nullable":true,"type":"string"},"invitedByName":{"nullable":true,"type":"string"},"name":{"nullable":true,"type":"string"},"permission":{"enum":["owner","editor","viewer"],"type":"string"},"userId":{"type":"string"}},"required":["id","userId","name","email","image","permission","invitedByName","createdAt"],"type":"object"},"CrmListSharing":{"nullable":true,"properties":{"canManageSharing":{"type":"boolean"},"orgWidePermission":{"enum":["viewer","editor"],"type":"string"},"owner":{"properties":{"email":{"nullable":true,"type":"string"},"image":{"nullable":true,"type":"string"},"name":{"nullable":true,"type":"string"},"userId":{"type":"string"}},"required":["userId","name","email","image"],"type":"object"},"ownerUserId":{"type":"string"},"shares":{"items":{"$ref":"#/components/schemas/CrmListShare"},"type":"array"},"visibility":{"enum":["private","organization","shared"],"type":"string"}},"required":["visibility","ownerUserId","owner","canManageSharing","orgWidePermission","shares"],"type":"object"},"CrmListSharingResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmListSharing"}},"required":["data"],"type":"object"},"CrmListUpdateBody":{"properties":{"name":{"type":"string"},"orgWidePermission":{"enum":["viewer","editor"],"type":"string"},"visibility":{"enum":["private","organization","shared"],"type":"string"}},"type":"object"},"CrmListUpdateResult":{"properties":{"data":{"allOf":[{"$ref":"#/components/schemas/CrmList"},{"nullable":true}]}},"required":["data"],"type":"object"},"CrmListWithMembers":{"properties":{"data":{"nullable":true,"properties":{"list":{"$ref":"#/components/schemas/CrmList"},"members":{"items":{"$ref":"#/components/schemas/CrmListMember"},"type":"array"}},"required":["list","members"],"type":"object"}},"required":["data"],"type":"object"},"CrmLoLoanMix":{"properties":{"data":{"properties":{"mix":{"items":{"properties":{"percentage":{"type":"number"},"type":{"type":"string"}},"required":["type","percentage"],"type":"object"},"type":"array"},"top":{"nullable":true,"type":"string"}},"required":["mix","top"],"type":"object"}},"required":["data"],"type":"object"},"CrmLoMomentum":{"properties":{"data":{"additionalProperties":{"properties":{"priorUnits":{"type":"number"},"recentUnits":{"type":"number"}},"required":["recentUnits","priorUnits"],"type":"object"},"type":"object"}},"required":["data"],"type":"object"},"CrmLoSponsorLocation":{"properties":{"data":{"additionalProperties":{"properties":{"location":{"type":"string"},"sponsored":{"type":"boolean"}},"required":["sponsored"],"type":"object"},"type":"object"}},"required":["data"],"type":"object"},"CrmMailProvider":{"enum":["google","microsoft",null],"nullable":true,"type":"string"},"CrmManualRecordResult":{"properties":{"data":{"properties":{"added":{"type":"boolean"},"entityId":{"type":"string"}},"required":["entityId","added"],"type":"object"}},"required":["data"],"type":"object"},"CrmMatchCandidate":{"properties":{"company":{"type":"string"},"location":{"type":"string"},"mmaId":{"type":"string"},"name":{"type":"string"},"nmlsId":{"type":"string"},"units":{"type":"number"},"volume":{"type":"number"}},"required":["name"],"type":"object"},"CrmMatchCandidates":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CrmMatchCandidate"},"type":"array"}},"required":["data"],"type":"object"},"CrmMeeting":{"properties":{"attendees":{"items":{"$ref":"#/components/schemas/CrmMeetingAttendee"},"type":"array"},"calendarEventId":{"nullable":true,"type":"string"},"calendarHtmlLink":{"nullable":true,"type":"string"},"calendarId":{"nullable":true,"type":"string"},"calendarProvider":{"$ref":"#/components/schemas/CrmMeetingProvider"},"calendarSyncedAt":{"nullable":true,"type":"number"},"cancelledAt":{"nullable":true,"type":"number"},"completedAt":{"nullable":true,"type":"number"},"createdAt":{"type":"number"},"createdByUserId":{"type":"string"},"description":{"nullable":true,"type":"string"},"endAt":{"type":"number"},"entityId":{"type":"string"},"icalUid":{"nullable":true,"type":"string"},"id":{"type":"string"},"listId":{"nullable":true,"type":"string"},"location":{"nullable":true,"type":"string"},"startAt":{"type":"number"},"status":{"$ref":"#/components/schemas/CrmMeetingStatus"},"timezone":{"nullable":true,"type":"string"},"title":{"type":"string"}},"required":["id","entityId","createdByUserId","title","description","startAt","endAt","timezone","location","status","listId","calendarProvider","calendarId","calendarEventId","icalUid","calendarHtmlLink","calendarSyncedAt","completedAt","cancelledAt","createdAt","attendees"],"type":"object"},"CrmMeetingAttendee":{"properties":{"email":{"type":"string"},"id":{"type":"string"},"isOrganizer":{"type":"boolean"},"kind":{"enum":["record","teammate","external"],"type":"string"},"name":{"nullable":true,"type":"string"},"responseStatus":{"enum":["needsAction","accepted","declined","tentative"],"type":"string"},"userId":{"nullable":true,"type":"string"}},"required":["id","kind","userId","email","name","responseStatus","isOrganizer"],"type":"object"},"CrmMeetingCreated":{"properties":{"data":{"$ref":"#/components/schemas/CrmMeeting"},"needsConnect":{"$ref":"#/components/schemas/CrmMeetingProvider"}},"required":["data"],"type":"object"},"CrmMeetingDeleted":{"properties":{"data":{"properties":{"deleted":{"type":"boolean"}},"required":["deleted"],"type":"object"}},"required":["data"],"type":"object"},"CrmMeetingList":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CrmMeeting"},"type":"array"}},"required":["data"],"type":"object"},"CrmMeetingProvider":{"enum":["google","microsoft",null],"nullable":true,"type":"string"},"CrmMeetingReconcileResult":{"properties":{"data":{"properties":{"applied":{"type":"number"}},"required":["applied"],"type":"object"}},"required":["data"],"type":"object"},"CrmMeetingStatus":{"enum":["scheduled","cancelled","completed"],"type":"string"},"CrmMeetingUpdateResult":{"properties":{"needsConnect":{"$ref":"#/components/schemas/CrmMeetingProvider"},"updated":{"type":"boolean"}},"required":["updated"],"type":"object"},"CrmMeetingUpdated":{"properties":{"data":{"$ref":"#/components/schemas/CrmMeetingUpdateResult"}},"required":["data"],"type":"object"},"CrmMemberFilter":{"properties":{"companyNmlsId":{"items":{"type":"string"},"type":"array"},"entityType":{"items":{"$ref":"#/components/schemas/CrmEntityType"},"type":"array"},"state":{"items":{"type":"string"},"type":"array"},"units":{"properties":{"gte":{"type":"number"},"lte":{"type":"number"}},"type":"object"},"volume":{"properties":{"gte":{"type":"number"},"lte":{"type":"number"}},"type":"object"}},"type":"object"},"CrmMemberIdsResult":{"properties":{"data":{"properties":{"entityIds":{"items":{"type":"string"},"type":"array"},"truncated":{"type":"boolean"}},"required":["entityIds","truncated"],"type":"object"}},"required":["data"],"type":"object"},"CrmMembersList":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CrmListMember"},"type":"array"}},"required":["data"],"type":"object"},"CrmMentionRecord":{"properties":{"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"location":{"nullable":true,"type":"string"},"name":{"type":"string"},"subtitle":{"nullable":true,"type":"string"}},"required":["entityId","entityType","name","subtitle","location"],"type":"object"},"CrmMentionSearch":{"properties":{"data":{"properties":{"results":{"items":{"$ref":"#/components/schemas/CrmMentionRecord"},"type":"array"}},"required":["results"],"type":"object"}},"required":["data"],"type":"object"},"CrmMiUpdatesResult":{"properties":{"data":{"properties":{"checkedAt":{"nullable":true,"type":"number"},"updates":{"items":{"properties":{"action":{"enum":["add","overwrite"],"type":"string"},"current":{"nullable":true,"type":"string"},"field":{"type":"string"},"id":{"type":"string"},"incoming":{"type":"string"},"kind":{"type":"string"},"label":{"type":"string"},"linkage":{"properties":{"companyNmlsId":{"type":"string"},"office":{"$ref":"#/components/schemas/CrmOverrideOffice"}},"type":"object"},"seenKey":{"type":"string"},"store":{"enum":["override","contact"],"type":"string"}},"required":["id","field","label","store","current","incoming","action","seenKey"],"type":"object"},"type":"array"}},"required":["updates","checkedAt"],"type":"object"}},"required":["data"],"type":"object"},"CrmObjectType":{"enum":["people","companies"],"type":"string"},"CrmOrgMember":{"properties":{"email":{"nullable":true,"type":"string"},"image":{"nullable":true,"type":"string"},"name":{"nullable":true,"type":"string"},"userId":{"type":"string"}},"required":["userId","name","email","image"],"type":"object"},"CrmOrgMemberList":{"properties":{"data":{"properties":{"members":{"items":{"$ref":"#/components/schemas/CrmOrgMember"},"type":"array"}},"required":["members"],"type":"object"}},"required":["data"],"type":"object"},"CrmOverlay":{"additionalProperties":{"type":"string"},"properties":{"office":{"$ref":"#/components/schemas/CrmOverrideOffice"}},"type":"object"},"CrmOverrideField":{"enum":["status","notes","title","company","companyType","firstName","lastName","location","city","state","zip","companyNmlsId","office"],"type":"string"},"CrmOverrideOffice":{"properties":{"city":{"type":"string"},"key":{"minLength":1,"type":"string"},"lat":{"type":"number"},"lon":{"type":"number"},"name":{"type":"string"},"state":{"type":"string"}},"required":["key"],"type":"object"},"CrmOverridesMap":{"properties":{"data":{"additionalProperties":{"$ref":"#/components/schemas/CrmOverlay"},"type":"object"}},"required":["data"],"type":"object"},"CrmPatchContactBody":{"oneOf":[{"properties":{"id":{"type":"string"},"isPrimary":{"type":"boolean"},"label":{"nullable":true,"type":"string"},"op":{"enum":["update"],"type":"string"},"value":{"nullable":true}},"required":["op","id"],"type":"object"},{"properties":{"entityId":{"type":"string"},"kind":{"$ref":"#/components/schemas/CrmContactKind"},"mmKey":{"type":"string"},"op":{"enum":["suppress"],"type":"string"}},"required":["op","entityId","kind","mmKey"],"type":"object"}]},"CrmPatchContactResult":{"properties":{"data":{"properties":{"id":{"type":"string"},"updated":{"type":"boolean"}},"type":"object"}},"required":["data"],"type":"object"},"CrmPlaceCallResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmCall"}},"required":["data"],"type":"object"},"CrmPollCallResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmCall"}},"required":["data"],"type":"object"},"CrmProductionEnrichJob":{"properties":{"data":{"properties":{"completedAt":{"type":"string"},"error":{"type":"string"},"failed":{"type":"number"},"jobId":{"type":"string"},"startedAt":{"type":"string"},"status":{"enum":["queued","running","completed","failed"],"type":"string"},"succeeded":{"type":"number"},"total":{"type":"number"}},"required":["jobId","status","total","succeeded","failed"],"type":"object"}},"required":["data"],"type":"object"},"CrmProfile":{"properties":{"data":{"nullable":true}},"type":"object"},"CrmRecordAccessFacts":{"properties":{"data":{"properties":{"accessibleUserIds":{"items":{"type":"string"},"type":"array"},"canManageShares":{"type":"boolean"},"everyone":{"type":"boolean"}},"required":["canManageShares","everyone","accessibleUserIds"],"type":"object"}},"required":["data"],"type":"object"},"CrmRecordAccessRequestInfo":{"properties":{"data":{"properties":{"alreadyHasAccess":{"type":"boolean"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"recordName":{"type":"string"},"requesterName":{"nullable":true,"type":"string"},"status":{"enum":["pending","granted","dismissed"],"type":"string"}},"required":["requesterName","recordName","entityType","status","alreadyHasAccess"],"type":"object"}},"required":["data"],"type":"object"},"CrmRecordConnections":{"properties":{"data":{"properties":{"colleagues":{"items":{"$ref":"#/components/schemas/CrmRelatedRecord"},"type":"array"},"inCrm":{"items":{"type":"string"},"type":"array"}},"required":["inCrm","colleagues"],"type":"object"}},"required":["data"],"type":"object"},"CrmRecordRef":{"properties":{"data":{"nullable":true,"properties":{"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"}},"required":["entityId","entityType"],"type":"object"}},"required":["data"],"type":"object"},"CrmRecordRequestAccessResult":{"properties":{"data":{"properties":{"ownerName":{"nullable":true,"type":"string"},"status":{"enum":["requested","already_requested","already_has_access"],"type":"string"}},"required":["status","ownerName"],"type":"object"}},"required":["data"],"type":"object"},"CrmRecordSearchResult":{"properties":{"data":{"properties":{"ids":{"items":{"type":"string"},"type":"array"}},"required":["ids"],"type":"object"}},"required":["data"],"type":"object"},"CrmRecordShare":{"properties":{"createdAt":{"type":"number"},"email":{"nullable":true,"type":"string"},"grantedByName":{"nullable":true,"type":"string"},"image":{"nullable":true,"type":"string"},"name":{"nullable":true,"type":"string"},"source":{"type":"string"},"userId":{"type":"string"}},"required":["userId","name","email","image","source","grantedByName","createdAt"],"type":"object"},"CrmRecordShareList":{"properties":{"data":{"properties":{"canManageShares":{"type":"boolean"},"shares":{"items":{"$ref":"#/components/schemas/CrmRecordShare"},"type":"array"}},"required":["canManageShares","shares"],"type":"object"}},"required":["data"],"type":"object"},"CrmRecordShareableMember":{"properties":{"email":{"nullable":true,"type":"string"},"image":{"nullable":true,"type":"string"},"name":{"nullable":true,"type":"string"},"userId":{"type":"string"}},"required":["userId","name","email","image"],"type":"object"},"CrmRecordShareableMemberList":{"properties":{"data":{"properties":{"members":{"items":{"$ref":"#/components/schemas/CrmRecordShareableMember"},"type":"array"}},"required":["members"],"type":"object"}},"required":["data"],"type":"object"},"CrmReferencedActivityEntry":{"allOf":[{"$ref":"#/components/schemas/CrmActivityEntry"},{"properties":{"sourceAccessible":{"type":"boolean"},"sourceEntityId":{"type":"string"},"sourceEntityType":{"$ref":"#/components/schemas/CrmEntityType"},"sourceHref":{"type":"string"},"sourceName":{"type":"string"}},"required":["sourceEntityId","sourceEntityType","sourceName","sourceHref","sourceAccessible"],"type":"object"}]},"CrmReferencedActivityList":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CrmReferencedActivityEntry"},"type":"array"}},"required":["data"],"type":"object"},"CrmRelatedRecord":{"properties":{"display":{"$ref":"#/components/schemas/CrmDisplay"},"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"listNames":{"items":{"type":"string"},"type":"array"}},"required":["entityId","entityType","display","listNames"],"type":"object"},"CrmRemoveContactResult":{"properties":{"data":{"properties":{"removed":{"type":"boolean"}},"required":["removed"],"type":"object"}},"required":["data"],"type":"object"},"CrmRemoveListMemberResult":{"properties":{"data":{"properties":{"removed":{"type":"boolean"}},"required":["removed"],"type":"object"}},"required":["data"],"type":"object"},"CrmRequestAccessResult":{"properties":{"data":{"properties":{"status":{"enum":["sent","already_requested"],"type":"string"}},"required":["status"],"type":"object"}},"required":["data"],"type":"object"},"CrmRevokeListAccessResult":{"properties":{"data":{"properties":{"revoked":{"type":"boolean"}},"required":["revoked"],"type":"object"}},"required":["data"],"type":"object"},"CrmRevokeRecordAccessResult":{"properties":{"data":{"properties":{"revoked":{"type":"boolean"}},"required":["revoked"],"type":"object"}},"required":["data"],"type":"object"},"CrmSetCustomValueResult":{"properties":{"data":{"properties":{"updated":{"type":"boolean"}},"required":["updated"],"type":"object"}},"required":["data"],"type":"object"},"CrmSetDefaultCallerIdResult":{"properties":{"data":{"properties":{"updated":{"type":"boolean"}},"required":["updated"],"type":"object"}},"required":["data"],"type":"object"},"CrmSetOverrideResult":{"properties":{"data":{"$ref":"#/components/schemas/CrmOverlay"},"derived":{"$ref":"#/components/schemas/CrmDerivedLocation"}},"required":["data"],"type":"object"},"CrmSetOwnerResult":{"properties":{"data":{"properties":{"canShare":{"type":"boolean"},"needsShare":{"type":"boolean"},"ownerUserId":{"type":"string"}},"required":["ownerUserId"],"type":"object"}},"required":["data"],"type":"object"},"CrmShareTemplateResult":{"properties":{"data":{"properties":{"granted":{"type":"boolean"}},"required":["granted"],"type":"object"}},"required":["data"],"type":"object"},"CrmShareableMember":{"properties":{"email":{"nullable":true,"type":"string"},"image":{"nullable":true,"type":"string"},"name":{"nullable":true,"type":"string"},"userId":{"type":"string"}},"required":["userId","name","email","image"],"type":"object"},"CrmShareableMemberList":{"properties":{"data":{"properties":{"members":{"items":{"$ref":"#/components/schemas/CrmShareableMember"},"type":"array"}},"required":["members"],"type":"object"}},"required":["data"],"type":"object"},"CrmSimilarOriginators":{"properties":{"data":{"properties":{"results":{"items":{"properties":{"components":{"properties":{"loan":{"nullable":true,"type":"number"},"size":{"type":"number"},"tx":{"nullable":true,"type":"number"}},"required":["tx","loan","size"],"type":"object"},"highlight":{"nullable":true,"properties":{"partnerPct":{"type":"number"},"type":{"type":"string"}},"required":["type","partnerPct"],"type":"object"},"nmls":{"type":"string"},"score":{"type":"number"},"units":{"type":"number"},"volume":{"type":"number"}},"required":["nmls","score","components","volume","units","highlight"],"type":"object"},"type":"array"}},"required":["results"],"type":"object"}},"required":["data"],"type":"object"},"CrmTask":{"properties":{"allDay":{"type":"boolean"},"assigneeUserId":{"type":"string"},"body":{"nullable":true,"type":"string"},"calendarEventId":{"nullable":true,"type":"string"},"calendarProvider":{"enum":["google","microsoft",null],"nullable":true,"type":"string"},"cancelledAt":{"nullable":true,"type":"number"},"completedAt":{"nullable":true,"type":"number"},"createdAt":{"type":"number"},"createdByUserId":{"type":"string"},"dueAt":{"nullable":true,"type":"number"},"entityId":{"type":"string"},"id":{"type":"string"},"listId":{"nullable":true,"type":"string"},"status":{"$ref":"#/components/schemas/CrmTaskStatus"},"title":{"type":"string"}},"required":["id","entityId","title","body","dueAt","allDay","status","assigneeUserId","createdByUserId","completedAt","cancelledAt","calendarProvider","calendarEventId","createdAt","listId"],"type":"object"},"CrmTaskCreated":{"properties":{"data":{"anyOf":[{"$ref":"#/components/schemas/CrmTask"},{"properties":{"canShare":{"type":"boolean"},"created":{"type":"boolean"},"needsShare":{"enum":[true],"type":"boolean"},"updated":{"type":"boolean"}},"required":["needsShare","canShare"],"type":"object"}]}},"required":["data"],"type":"object"},"CrmTaskDeleted":{"properties":{"data":{"properties":{"deleted":{"type":"boolean"}},"required":["deleted"],"type":"object"}},"required":["data"],"type":"object"},"CrmTaskList":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CrmTask"},"type":"array"}},"required":["data"],"type":"object"},"CrmTaskStatus":{"enum":["open","completed","cancelled"],"type":"string"},"CrmTaskUpdated":{"properties":{"data":{"anyOf":[{"properties":{"updated":{"type":"boolean"}},"required":["updated"],"type":"object"},{"properties":{"canShare":{"type":"boolean"},"created":{"type":"boolean"},"needsShare":{"enum":[true],"type":"boolean"},"updated":{"type":"boolean"}},"required":["needsShare","canShare"],"type":"object"},{"properties":{"needsConnect":{"enum":["google","microsoft"],"type":"string"},"task":{"$ref":"#/components/schemas/CrmTask"}},"required":["task"],"type":"object"}]}},"required":["data"],"type":"object"},"CrmTemplate":{"properties":{"data":{"allOf":[{"$ref":"#/components/schemas/CrmTemplateWithFields"},{"nullable":true}]}},"required":["data"],"type":"object"},"CrmTemplateField":{"properties":{"config":{"additionalProperties":{"nullable":true},"nullable":true,"type":"object"},"id":{"type":"string"},"key":{"type":"string"},"label":{"type":"string"},"options":{"items":{"properties":{"color":{"type":"string"},"id":{"type":"string"},"label":{"type":"string"}},"required":["id","label"],"type":"object"},"nullable":true,"type":"array"},"sortOrder":{"type":"number"},"type":{"enum":["text","number","currency","date","select","multiselect","url","rating","checkbox","status","tags"],"type":"string"}},"required":["id","key","label","type","options","config","sortOrder"],"type":"object"},"CrmTemplateList":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CrmTemplateSummary"},"type":"array"}},"required":["data"],"type":"object"},"CrmTemplateShareList":{"properties":{"data":{"$ref":"#/components/schemas/CrmTemplateShares"}},"required":["data"],"type":"object"},"CrmTemplateShares":{"properties":{"canManage":{"type":"boolean"},"owner":{"properties":{"email":{"nullable":true,"type":"string"},"image":{"nullable":true,"type":"string"},"name":{"nullable":true,"type":"string"},"userId":{"type":"string"}},"required":["userId","name","email","image"],"type":"object"},"ownerUserId":{"type":"string"},"shares":{"items":{"properties":{"createdAt":{"type":"number"},"email":{"nullable":true,"type":"string"},"grantedByName":{"nullable":true,"type":"string"},"image":{"nullable":true,"type":"string"},"name":{"nullable":true,"type":"string"},"userId":{"type":"string"}},"required":["userId","name","email","image","grantedByName","createdAt"],"type":"object"},"type":"array"}},"required":["ownerUserId","owner","canManage","shares"],"type":"object"},"CrmTemplateSummary":{"properties":{"canManage":{"type":"boolean"},"createdAt":{"type":"number"},"fieldCount":{"type":"number"},"id":{"type":"string"},"name":{"type":"string"},"objectType":{"$ref":"#/components/schemas/CrmObjectType"},"ownerName":{"nullable":true,"type":"string"},"ownerUserId":{"type":"string"},"sharedCount":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","name","objectType","ownerUserId","sharedCount","fieldCount","createdAt","updatedAt","ownerName","canManage"],"type":"object"},"CrmTemplateWithFields":{"properties":{"createdAt":{"type":"number"},"fieldCount":{"type":"number"},"fields":{"items":{"$ref":"#/components/schemas/CrmTemplateField"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"objectType":{"$ref":"#/components/schemas/CrmObjectType"},"ownerUserId":{"type":"string"},"sharedCount":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","name","objectType","ownerUserId","sharedCount","fieldCount","createdAt","updatedAt","fields"],"type":"object"},"CrmTranscriptSentence":{"properties":{"speaker":{"enum":["user","contact"],"type":"string"},"text":{"type":"string"}},"required":["speaker","text"],"type":"object"},"CrmTransferListOwnershipResult":{"properties":{"data":{"properties":{"transferred":{"type":"boolean"}},"required":["transferred"],"type":"object"}},"required":["data"],"type":"object"},"CrmUnshareTemplateResult":{"properties":{"data":{"properties":{"revoked":{"type":"boolean"}},"required":["revoked"],"type":"object"}},"required":["data"],"type":"object"},"CrmUpdateListFieldResult":{"properties":{"data":{"properties":{"updated":{"type":"boolean"}},"required":["updated"],"type":"object"}},"required":["data"],"type":"object"},"CrmUpdateTemplateResult":{"properties":{"data":{"properties":{"updated":{"type":"boolean"}},"required":["updated"],"type":"object"}},"required":["data"],"type":"object"},"CrmWorkspaceMeeting":{"allOf":[{"$ref":"#/components/schemas/CrmMeeting"},{"properties":{"canManage":{"type":"boolean"},"display":{"allOf":[{"$ref":"#/components/schemas/CrmDisplay"},{"nullable":true}]},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"overrides":{"$ref":"#/components/schemas/CrmOverlay"},"recordName":{"type":"string"},"recordSubtitle":{"nullable":true,"type":"string"}},"required":["entityType","recordName","recordSubtitle","display","canManage"],"type":"object"}]},"CrmWorkspaceMeetingList":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CrmWorkspaceMeeting"},"type":"array"}},"required":["data"],"type":"object"},"CrmWorkspaceTask":{"allOf":[{"$ref":"#/components/schemas/CrmTask"},{"properties":{"canDelete":{"type":"boolean"},"display":{"allOf":[{"$ref":"#/components/schemas/CrmDisplay"},{"nullable":true}]},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"overrides":{"$ref":"#/components/schemas/CrmOverlay"},"recordName":{"type":"string"},"recordSubtitle":{"nullable":true,"type":"string"}},"required":["entityType","recordName","recordSubtitle","display","canDelete"],"type":"object"}]},"CrmWorkspaceTaskList":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CrmWorkspaceTask"},"type":"array"}},"required":["data"],"type":"object"},"DateFilterValue":{"anyOf":[{"description":"Exact date","example":"2024-01-01","type":"string"},{"description":"Date range. Excludes null/missing-field docs by default; add `includeNulls: true` to keep them. Bounds accept `YYYY`, `YYYY-MM`, `YYYY-MM-DD` or a full ISO datetime. 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.","example":{"gte":"2024-01-01","lte":"2024-12-31"},"properties":{"gt":{"type":"string"},"gte":{"type":"string"},"includeNulls":{"description":"Also keep docs where the field is null/missing (a range filter drops them by default). Requires a bound.","type":"boolean"},"lt":{"type":"string"},"lte":{"type":"string"}},"type":"object"},{"nullable":true}]},"EnrichAmbiguousRef":{"properties":{"alternates":{"description":"Sibling document `id`s — pass one back as `/{id}/enrich` to enrich that exact unit.","items":{"type":"string"},"type":"array"},"error":{"type":"string"}},"required":["error","alternates"],"type":"object"},"EnrichBatchItem":{"properties":{"alternates":{"description":"Sibling document `id`s. Present only on `ambiguous_ref` — pass one as a precise id to enrich that exact unit.","items":{"type":"string"},"type":"array"},"balance":{"description":"Remaining credit balance. Present only on insufficient_credits.","type":"number"},"cached":{"description":"Served from cache (member entitlement or internal). ok items only.","type":"boolean"},"charged":{"description":"True when this id resulted in a credit debit. ok items only.","type":"boolean"},"code":{"$ref":"#/components/schemas/EnrichBatchItemErrorCode"},"data":{"$ref":"#/components/schemas/PropertyEnrichment"},"property":{"description":"The parcel behind this enrichment. ok items only; `null` when the id resolved to more than one parcel.","nullable":true,"properties":{"communityLending":{"$ref":"#/components/schemas/PropertyCommunityLending"},"parties":{"$ref":"#/components/schemas/PropertyParties"}},"required":["communityLending","parties"],"type":"object"},"propertyId":{"type":"string"},"reason":{"$ref":"#/components/schemas/EnrichmentReason"},"result":{"$ref":"#/components/schemas/EnrichmentResultMeta"},"status":{"enum":["ok","error"],"type":"string"}},"required":["propertyId","status"],"type":"object"},"EnrichBatchItemErrorCode":{"description":"Failure reason. error items only.","enum":["not_found","ambiguous_ref","no_address","provider_error","insufficient_credits","rate_limited","daily_limit_exceeded","permission_denied","member_not_found","bad_request","billing_unavailable"],"type":"string"},"EnrichBatchRequest":{"properties":{"propertyIds":{"description":"Property ids to enrich in one request. 1–50; larger sets must use the async bulk job. Use the `id`/`mmPropertyId` from a property search or a loan/sale record (e.g. `mm_<fips><apn>`) — bare APNs, fips+apn, or `loan_…` ids will not resolve.","items":{"minLength":1,"type":"string"},"maxItems":50,"minItems":1,"type":"array"},"refresh":{"description":"When true, bypass both caches for every id, force a fresh skip-trace, and re-charge per match.","type":"boolean"}},"required":["propertyIds"],"type":"object"},"EnrichBatchResponse":{"properties":{"results":{"items":{"$ref":"#/components/schemas/EnrichBatchItem"},"type":"array"},"summary":{"$ref":"#/components/schemas/EnrichBatchSummary"}},"required":["results","summary"],"type":"object"},"EnrichBatchSummary":{"properties":{"charged":{"description":"Items that resulted in a credit debit (one per match).","type":"integer"},"failed":{"description":"Items with status error.","type":"integer"},"requested":{"type":"integer"},"succeeded":{"description":"Items with status ok (cache hits + fresh, matched or empty).","type":"integer"}},"required":["requested","succeeded","charged","failed"],"type":"object"},"EnrichBulkJobResponse":{"properties":{"billingStatus":{"description":"Outcome of the job's single finalize debit: `charged`, `capped` (member balance/daily cap hit — customer constraint), `billing_error` (5xx/auth — recoverable revenue to reconcile), or `none` (nothing matched). Absent on older rows.","enum":["charged","capped","billing_error","none"],"type":"string"},"chargedCount":{"description":"Intended charge — matched rows tallied during the run. NOT necessarily what was billed; read `creditsCharged` for the actual debit and `billingStatus` for why they differ.","type":"integer"},"completedAt":{"type":"string"},"creditsCharged":{"description":"Credits ACTUALLY debited (0 when the finalize debit was rejected/failed). Absent on older rows — fall back to `chargedCount`.","type":"integer"},"downloadUrl":{"description":"Stable, shareable download link for the completed results. Forces a file download (with a friendly filename) and stays valid for 7 days after completion. Present once `status` is `completed`. This is the link to hand to a user or send by email.","type":"string"},"error":{"type":"string"},"failed":{"type":"integer"},"fromCache":{"type":"integer"},"jobId":{"type":"string"},"resultsUrl":{"description":"Direct download URL for the completed results. Long-lived per request but changes on each poll; prefer `downloadUrl` for a stable link to share.","type":"string"},"startedAt":{"type":"string"},"status":{"enum":["queued","running","completed","failed"],"type":"string"},"succeeded":{"type":"integer"},"total":{"type":"integer"}},"required":["jobId","status","total","succeeded","failed","fromCache","chargedCount"],"type":"object"},"EnrichBulkRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode","description":"Filter-driven mode: an advanced boolean filter tree, AND-merged with `flatFilters` (same semantics as `POST /properties`)."},"filters":{"$ref":"#/components/schemas/FilterNode","description":"Legacy alias for `advancedFilters`."},"flatFilters":{"allOf":[{"$ref":"#/components/schemas/PropertyFlatFilters"},{"description":"Filter-driven mode: the same flat filters as `POST /properties` (including the loan-slot filters). The job enriches every matching property up to `limit` (or the hard cap). Provide filters OR propertyIds, not both."}]},"limit":{"description":"Filter-driven mode only: cap the number of matching properties enriched (and billed). Omitted → enrich every match up to the 50000 hard cap.","maximum":50000,"minimum":1,"type":"integer"},"propertyIds":{"description":"Property IDs to enrich (id-driven mode). Hard cap 50000. Use the `id`/`mmPropertyId` from a property search or a loan/sale record (e.g. `mm_<fips><apn>`) — bare APNs, fips+apn, or `loan_…` ids will not resolve. Provide this OR filters, not both.","items":{"minLength":1,"type":"string"},"maxItems":50000,"minItems":1,"type":"array"},"refresh":{"description":"When true, the ECS task bypasses both caches for every property and re-charges credits. Idempotency key picks up an epoch-minute discriminator.","type":"boolean"}},"type":"object"},"EnrichBulkResponse":{"properties":{"estimatedCost":{"description":"Worst-case credit cost (1 / property). Actual debit is per match — properties with no skip-trace contacts and cached no-match rows don't charge. The post-completion `chargedCount` on the job row is the precise debited total.","type":"integer"},"jobId":{"type":"string"},"propertyCount":{"type":"integer"},"status":{"enum":["queued"],"type":"string"}},"required":["jobId","status","propertyCount","estimatedCost"],"type":"object"},"EnrichPropertyContext":{"description":"The parcel behind the enrichment: its Community Lending neighborhood profile and the mortgage parties attributed to it. Identical to the `communityLending` and `parties` blocks on `GET /v1/properties/{id}` — returned here so a skip-trace does not need a second call to answer 'what kind of neighborhood is this' and 'who already has a relationship with this parcel'.","nullable":true,"properties":{"communityLending":{"$ref":"#/components/schemas/PropertyCommunityLending"},"parties":{"$ref":"#/components/schemas/PropertyParties"}},"required":["communityLending","parties"],"type":"object"},"EnrichPropertyResponse":{"properties":{"cached":{"description":"Whether the result was served from cache","type":"boolean"},"charged":{"description":"True when this call resulted in a credit debit. False on cache hits AND on `fresh_skip_trace_empty` (no-match calls don't charge).","type":"boolean"},"data":{"$ref":"#/components/schemas/PropertyEnrichment"},"property":{"$ref":"#/components/schemas/EnrichPropertyContext"},"reason":{"$ref":"#/components/schemas/EnrichmentReason"},"result":{"$ref":"#/components/schemas/EnrichmentResultMeta"}},"required":["data","cached","charged","reason","result"],"type":"object"},"EnrichmentCacheBustRequest":{"properties":{"rows":{"description":"Explicit list of cache rows to delete. Mix internal and member keys freely. Max 500 per call; the helper batches into 25-item DDB `BatchWriteItem` chunks under the hood.","items":{"$ref":"#/components/schemas/EnrichmentCacheRowKey"},"maxItems":500,"minItems":1,"type":"array"}},"required":["rows"],"type":"object"},"EnrichmentCacheBustResponse":{"properties":{"deleted":{"minimum":0,"type":"integer"},"unprocessed":{"items":{"$ref":"#/components/schemas/EnrichmentCacheRowKey"},"type":"array"}},"required":["deleted","unprocessed"],"type":"object"},"EnrichmentCacheDeleteResponse":{"properties":{"deleted":{"enum":[true],"type":"boolean"}},"required":["deleted"],"type":"object"},"EnrichmentCacheGetResponse":{"properties":{"data":{"$ref":"#/components/schemas/EnrichmentCacheRow"}},"required":["data"],"type":"object"},"EnrichmentCachePropertyChildrenResponse":{"properties":{"internal":{"allOf":[{"$ref":"#/components/schemas/EnrichmentCacheRow"},{"description":"The internal property cache row, or `null` if the property has no cached enrichment.","nullable":true}]},"members":{"description":"Every member entitlement row tied to this property. Empty when no member has enriched it.","items":{"$ref":"#/components/schemas/EnrichmentCacheRow"},"type":"array"}},"required":["internal","members"],"type":"object"},"EnrichmentCacheRow":{"properties":{"data":{"description":"Parsed `PropertyEnrichment` payload, or `null` if the row failed schema parse (drift). Admin-view exposes both.","nullable":true},"enrichedAt":{"nullable":true,"type":"string"},"expired":{"type":"boolean"},"expiresAt":{"nullable":true,"type":"number"},"key":{"$ref":"#/components/schemas/EnrichmentCacheRowKey"},"personCount":{"description":"Number of skip-trace persons cached in this row. `0` usually means the provider had no contact match — but rows from the May 2026 parser-drift incident also surface here.","minimum":0,"type":"integer"},"source":{"nullable":true,"type":"string"}},"required":["key","personCount","enrichedAt","source","expiresAt","expired"],"type":"object"},"EnrichmentCacheRowKey":{"oneOf":[{"properties":{"kind":{"enum":["internal"],"type":"string"},"propertyId":{"type":"string"}},"required":["kind","propertyId"],"type":"object"},{"properties":{"kind":{"enum":["member"],"type":"string"},"orgId":{"type":"string"},"propertyId":{"type":"string"},"userId":{"type":"string"}},"required":["kind","orgId","userId","propertyId"],"type":"object"}]},"EnrichmentCacheScanResponse":{"properties":{"cursor":{"description":"Pagination cursor. Pass back unchanged on the next call.","type":"string"},"items":{"items":{"$ref":"#/components/schemas/EnrichmentCacheRow"},"type":"array"}},"required":["items"],"type":"object"},"EnrichmentListItem":{"properties":{"enrichedAt":{"type":"string"},"personCount":{"type":"number"},"propertyId":{"type":"string"},"source":{"type":"string"}},"required":["propertyId","enrichedAt","source","personCount"],"type":"object"},"EnrichmentListResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/EnrichmentListItem"},"type":"array"}},"required":["data"],"type":"object"},"EnrichmentReason":{"description":"Pipeline path used to produce this enrichment. Pair with `charged` to drive billing UX; pair with `data.persons` to drive the empty-state UX.","enum":["member_cache_hit","internal_cache_hit","internal_cache_hit_empty","fresh_skip_trace","fresh_skip_trace_empty"],"type":"string"},"EnrichmentResultMeta":{"description":"Per-batch counts BatchData echoed back (or all-zero on cache hits). `matched` > 0 implies a fresh hit; `noMatch` > 0 with `matched: 0` implies a genuine no-match.","properties":{"error":{"minimum":0,"type":"integer"},"matched":{"minimum":0,"type":"integer"},"noMatch":{"minimum":0,"type":"integer"},"requested":{"minimum":0,"type":"integer"}},"required":["requested","matched","noMatch","error"],"type":"object"},"EntityCommunityLending":{"description":"Community Lending — the neighborhood (U.S. Census tract) mix of the loans this entity produced in the selected period: program shares and counts, the averaged neighborhood profile, and the local mortgage market. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100. Every share is taken over `loansWithCommunityData`, NOT over the entity's total production. Two fields are deliberately not 0-100: `avgIncomeVsMetroPct` is a ratio where 100 means parity with the metro (it exceeds 100), and `ruralGradient` is an ordinal 1-10 code. `null` — not an all-null object — when the entity had no tract-resolved loans in the window. Returned by the entity DETAIL routes only (`getOriginator` / `getCompany` / `getBranch`); list rows omit the block. Every key here is also a filter key on the matching list route.","nullable":true,"properties":{"affordableHousingTractCount":{"description":"Loans in qualified affordable-housing neighborhoods, as a count. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"affordableHousingTractPct":{"description":"Share of the entity's tract-resolved loans in qualified neighborhoods for affordable-housing programs, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgAsianPct":{"description":"Mean Asian (non-Hispanic) share of the population in those neighborhoods, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgBlackPct":{"description":"Mean Black (non-Hispanic) share of the population in those neighborhoods, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgDenialRate":{"description":"Mean share of mortgage applications denied in those neighborhoods, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgFamilyIncome":{"description":"Mean median family income of those neighborhoods, in whole dollars. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgHispanicPct":{"description":"Mean Hispanic or Latino share of the population in those neighborhoods, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgHomeValue":{"description":"Mean median home value across those neighborhoods, in whole dollars — a neighborhood statistic, not the entity's average loan size (`avgLoanAmount`). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgHomeownershipRate":{"description":"Mean owner-occupied share of housing units in those neighborhoods, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgHouseholdIncome":{"description":"Mean median household income of those neighborhoods, in whole dollars. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgIncomeVsMetroPct":{"description":"Mean neighborhood income relative to its metro area, where 100 is parity. Legitimately exceeds 100 — a ratio, not a share. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgLowModHouseholdPct":{"description":"Mean HUD block-group low/moderate-income HOUSEHOLD share across those neighborhoods, 0-100 — a finer measure than `lowModIncomeTractPct`, which counts whole neighborhoods. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgMedianAge":{"description":"Mean median age of the population in those neighborhoods, in years. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgMilesToCollege":{"description":"Mean straight-line distance to the nearest college, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgMilesToSchool":{"description":"Mean straight-line distance to the nearest school, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgMilesToWorship":{"description":"Mean straight-line distance to the nearest place of worship, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgMinorityPct":{"description":"Mean non-white share of the population in those neighborhoods, 0-100. `majorityMinorityTractPct` is the per-neighborhood-threshold form of the same question. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgPopulation":{"description":"Mean population of those neighborhoods. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgPovertyRate":{"description":"Mean share of the population below the poverty line in those neighborhoods, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgTractApplications":{"description":"Mean number of mortgage applications reported in those neighborhoods, over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgTractLoanVolume":{"description":"Mean mortgage dollar volume reported in those neighborhoods, over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgTractOriginations":{"description":"Mean number of mortgage originations reported in those neighborhoods, over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgWhiteNonHispanicPct":{"description":"Mean White (non-Hispanic) share of the population in those neighborhoods, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"difficultDevelopmentAreaCount":{"description":"Loans in HUD-designated difficult development areas, as a count. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"difficultDevelopmentAreaPct":{"description":"Share of the entity's tract-resolved loans in HUD-designated difficult development areas, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"distressedTractCount":{"description":"Loans in distressed-or-underserved neighborhoods, as a count. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"distressedTractPct":{"description":"Share of the entity's tract-resolved loans in distressed-or-underserved nonmetropolitan middle-income neighborhoods, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"floodHazardTractCount":{"description":"Loans in a FEMA special flood hazard area, as a count. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"floodHazardTractPct":{"description":"Share of the entity's tract-resolved loans in a FEMA special flood hazard area, 0-100. `predominantFloodZone` names the specific zone. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"loansWithCommunityData":{"description":"How many of the entity's loans in the selected period resolved to a neighborhood — the DENOMINATOR every share in this block is taken over. Read it first: a 100% share off two loans is not a 100% share off two hundred. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"lowModIncomeTractCount":{"description":"Loans in low- or moderate-income neighborhoods, as a count. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"lowModIncomeTractPct":{"description":"Share of the entity's tract-resolved loans in low- or moderate-income neighborhoods under the Community Reinvestment Act, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"majorityMinorityTractCount":{"description":"Loans in majority-minority neighborhoods, as a count. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"majorityMinorityTractPct":{"description":"Share of the entity's tract-resolved loans in majority-minority neighborhoods, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"opportunityZoneCount":{"description":"Loans in Opportunity Zones, as a count. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"opportunityZonePct":{"description":"Share of the entity's tract-resolved loans in federally designated Opportunity Zones, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"predominantFloodZone":{"description":"FEMA flood-zone code most common across those neighborhoods (e.g. `AE`). Null means no special flood hazard area on file. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"string"},"predominantIncomeLevel":{"description":"The relative-income classification most of the entity's loans landed in: low, moderate, middle or upper. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","enum":["low","moderate","middle","upper",null],"nullable":true,"type":"string"},"ruralGradient":{"description":"Mean remoteness of those neighborhoods on an ORDINAL 1-10 scale (1 = metropolitan core, 10 = most remote). A code, not a percent. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"ruralTractCount":{"description":"Loans in rural neighborhoods, as a count. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"ruralTractPct":{"description":"Share of the entity's tract-resolved loans in rural neighborhoods, 0-100. `ruralGradient` is the finer, ordinal form. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"usdaEligibleTractCount":{"description":"Loans in USDA-eligible neighborhoods, as a count. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"usdaEligibleTractPct":{"description":"Share of the entity's tract-resolved loans in neighborhoods eligible for USDA rural housing programs, 0-100. Broader than `ruralTractPct`. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"}},"required":["loansWithCommunityData","lowModIncomeTractPct","lowModIncomeTractCount","majorityMinorityTractPct","majorityMinorityTractCount","ruralTractPct","ruralTractCount","opportunityZonePct","opportunityZoneCount","affordableHousingTractPct","affordableHousingTractCount","floodHazardTractPct","floodHazardTractCount","usdaEligibleTractPct","usdaEligibleTractCount","distressedTractPct","distressedTractCount","difficultDevelopmentAreaPct","difficultDevelopmentAreaCount","predominantIncomeLevel","predominantFloodZone","avgHouseholdIncome","avgFamilyIncome","avgHomeValue","avgMedianAge","avgPopulation","avgMinorityPct","avgIncomeVsMetroPct","avgDenialRate","avgHomeownershipRate","avgPovertyRate","avgLowModHouseholdPct","avgWhiteNonHispanicPct","avgBlackPct","avgAsianPct","avgHispanicPct","avgTractOriginations","avgTractApplications","avgTractLoanVolume","ruralGradient","avgMilesToSchool","avgMilesToCollege","avgMilesToWorship"],"type":"object"},"EntityPredominantFloodZoneFilterValue":{"anyOf":[{"description":"One of (case-insensitive): A, AE, AH, AO, A99, V, VE","enum":["A","AE","AH","AO","A99","V","VE"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): A, AE, AH, AO, A99, V, VE","enum":["A","AE","AH","AO","A99","V","VE"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"EntityPredominantIncomeLevelFilterValue":{"anyOf":[{"description":"One of (case-insensitive): low, moderate, middle, upper","enum":["low","moderate","middle","upper"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): low, moderate, middle, upper","enum":["low","moderate","middle","upper"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"ErrorResponse":{"properties":{"error":{"description":"Error message","type":"string"}},"required":["error"],"type":"object"},"FieldCondition":{"properties":{"field":{"type":"string"},"op":{"$ref":"#/components/schemas/FilterOp"},"type":{"enum":["filter"],"type":"string"},"value":{"description":"Comparison value","nullable":true}},"required":["type","field","op"],"type":"object"},"FilterNode":{"anyOf":[{"$ref":"#/components/schemas/AndFilter"},{"$ref":"#/components/schemas/OrFilter"},{"$ref":"#/components/schemas/NotFilter"},{"$ref":"#/components/schemas/FieldCondition"}]},"FilterOp":{"description":"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.","enum":["eq","neq","gt","gte","lt","lte","between","in","match","geoDistance","exists"],"type":"string"},"FootprintProductFilter":{"additionalProperties":false,"description":"Correlate a product INSIDE this lender relationship — 'FHA business through this lender'.","properties":{"avgLoanAmount":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"Mean loan size of this product INSIDE the named market."}]},"key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"description":"Product key(s), lowercase — e.g. `fha`, `conventional`, `va` for `loanType`; `purchase`, `refinance` for `transactionType`."},"mix":{"description":"Which product breakdown inside the market — loan type (fha, conventional, va, …) or transaction type (purchase, refinance, …).","enum":["loanType","transactionType"],"type":"string"},"shareOfUnits":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"This product's share of the market's loan count, as a 0–100 PERCENT (not a 0–1 fraction)."}]},"shareOfVolume":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"This product's share of the market's dollar volume, as a 0–100 PERCENT (not a 0–1 fraction)."}]},"units":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"Loan count of this product INSIDE the named market."}]},"volume":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"Dollar volume of this product INSIDE the named market, for the selected period."}]}},"type":"object"},"FootprintRange":{"additionalProperties":false,"description":"Dollar volume of the agent's sales financed BY this lender during the selected period — evaluated inside that lender's own bucket, not against the agent's total.","properties":{"gt":{"type":"number"},"gte":{"type":"number"},"lt":{"type":"number"},"lte":{"type":"number"}},"type":"object"},"GeoFilterValue":{"description":"Radius search around an agent's office — `{ lat, lon, radius }` (e.g. radius \"15mi\" or \"24km\").","nullable":true,"properties":{"lat":{"type":"number"},"lon":{"type":"number"},"radius":{"example":"25mi","type":"string"}},"required":["lat","lon","radius"],"type":"object"},"HubspotError":{"properties":{"code":{"description":"Stable reason code. `not_connected` means run the HubSpot connect flow; `portal_mismatch` means the connected account is not the one the workspace's mapping was built for; the rest describe a setup problem to fix before retrying.","type":"string"},"details":{"additionalProperties":{"nullable":true},"type":"object"},"error":{"description":"Human-readable explanation.","type":"string"}},"required":["error","code"],"type":"object"},"HubspotObjectStatus":{"properties":{"code":{"type":"string"},"entity":{"description":"The kind of Model Match record the ids refer to — `originator` for loan officers, `agent` for real estate agents. Required, and checked against what your workspace configured: if they disagree the request is refused rather than writing records built from the wrong mapping.","enum":["agent","originator"],"type":"string"},"mappedFieldCount":{"type":"number"},"matchOn":{"description":"The HubSpot field used to match existing records.","type":"string"},"object":{"description":"Which kind of HubSpot record to write. Your workspace decides which Model Match records feed each one.","enum":["contact","company"],"type":"string"},"ready":{"type":"boolean"},"reason":{"type":"string"}},"required":["object","ready"],"type":"object"},"HubspotPaymentRequired":{"properties":{"balance":{"description":"Credits available.","type":"number"},"cost":{"description":"Credits this push would cost at most.","type":"number"},"error":{"type":"string"}},"required":["error","balance","cost"],"type":"object"},"HubspotPushRecordResult":{"properties":{"crmRecordId":{"description":"The record's id in your HubSpot account, when written.","type":"string"},"id":{"type":"string"},"message":{"type":"string"},"preserved":{"description":"Fields left untouched because your HubSpot record already had a value and the mapping says not to overwrite.","items":{"type":"string"},"type":"array"},"reason":{"enum":["not_found","missing_dedupe_value","duplicate_dedupe_value","rejected"],"type":"string"},"status":{"enum":["created","updated","skipped","failed","would_create","would_update"],"type":"string"}},"required":["id","status"],"type":"object"},"HubspotPushRequest":{"properties":{"dryRun":{"default":false,"description":"Resolve the records, apply the mapping and report exactly what would be written — without writing anything. There is no undo on a real push; use this first.","type":"boolean"},"entity":{"description":"The kind of Model Match record the ids refer to — `originator` for loan officers, `agent` for real estate agents. Required, and checked against what your workspace configured: if they disagree the request is refused rather than writing records built from the wrong mapping.","enum":["agent","originator"],"type":"string"},"ids":{"description":"Record ids to send, at most 100 per request. Loan officers are identified by NMLS id, agents by their Model Match id. Duplicates are collapsed.","items":{"minLength":1,"type":"string"},"maxItems":100,"minItems":1,"type":"array"},"object":{"description":"Which kind of HubSpot record to write. Your workspace decides which Model Match records feed each one.","enum":["contact","company"],"type":"string"}},"required":["object","entity","ids"],"type":"object"},"HubspotPushResponse":{"properties":{"billing":{"properties":{"charged":{"nullable":true,"type":"number"},"note":{"type":"string"}},"required":["charged"],"type":"object"},"dryRun":{"type":"boolean"},"entity":{"description":"The kind of Model Match record the ids refer to — `originator` for loan officers, `agent` for real estate agents. Required, and checked against what your workspace configured: if they disagree the request is refused rather than writing records built from the wrong mapping.","enum":["agent","originator"],"type":"string"},"object":{"description":"Which kind of HubSpot record to write. Your workspace decides which Model Match records feed each one.","enum":["contact","company"],"type":"string"},"portalId":{"description":"The HubSpot account these records were written to.","type":"string"},"portalRecorded":{"description":"Whether your workspace's setup records which HubSpot account it was built for. When false, consider saving it so a member on a different account can be warned before sending.","type":"boolean"},"results":{"items":{"$ref":"#/components/schemas/HubspotPushRecordResult"},"type":"array"},"summary":{"properties":{"created":{"type":"number"},"failed":{"type":"number"},"requested":{"type":"number"},"skipped":{"type":"number"},"updated":{"type":"number"}},"required":["requested","created","updated","skipped","failed"],"type":"object"}},"required":["object","entity","dryRun","portalId","portalRecorded","summary","results","billing"],"type":"object"},"HubspotStatusResponse":{"properties":{"configuredPortalId":{"description":"The HubSpot account your workspace's setup was built for. When this differs from `portalId`, pushes are refused.","nullable":true,"type":"string"},"connected":{"type":"boolean"},"maxRecordsPerPush":{"type":"number"},"objects":{"items":{"$ref":"#/components/schemas/HubspotObjectStatus"},"type":"array"},"portalId":{"description":"The HubSpot account you have connected, when known.","nullable":true,"type":"string"},"portalMismatch":{"type":"boolean"}},"required":["connected","portalId","configuredPortalId","portalMismatch","maxRecordsPerPush","objects"],"type":"object"},"InstantSearchRequest":{"properties":{"entities":{"description":"Entity types to search (default: all)","items":{"type":"string"},"type":"array"},"filters":{"additionalProperties":{"type":"string"},"description":"Per-entity filter strings","type":"object"},"limit":{"description":"Max results per entity (default: 5)","maximum":50,"minimum":1,"type":"integer"},"query":{"description":"Search query","minLength":1,"type":"string"}},"required":["query"],"type":"object"},"InstantSearchResponse":{"properties":{"results":{"additionalProperties":{"items":{"nullable":true},"type":"array"},"type":"object"}},"required":["results"],"type":"object"},"Interval":{"enum":["weekly","monthly","quarterly","yearly"],"type":"string"},"LenderDetail":{"allOf":[{"$ref":"#/components/schemas/LenderSummary"},{"properties":{},"type":"object"}]},"LenderDetailResponse":{"properties":{"data":{"$ref":"#/components/schemas/LenderDetail"}},"required":["data"],"type":"object"},"LenderFilterEntry":{"properties":{"canonical":{"description":"Canonical lender name (the `value` from lender autocomplete). Resolved to a lender id server-side; pass `id` instead when you have one.","type":"string"},"displayName":{"description":"Label / typed search string","type":"string"},"id":{"description":"Lender-dictionary id — the `id` from instantSearch / listLenders (e.g. \"mortgage_rocket\" or \"mortgage rocket\"), and the same value the `lender` filter takes. PREFERRED: matched directly against the stored lender key with no name resolution. `canonical` is still accepted and resolved server-side.","type":"string"},"mode":{"enum":["include","exclude"],"type":"string"},"percentMin":{"description":"Minimum percent_of_volume (0–100); 0/undefined = > 0%","maximum":100,"minimum":0,"type":"number"},"type":{"enum":["canonical","freetext"],"type":"string"}},"required":["displayName"],"type":"object"},"LenderListRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"mode":{"enum":["and","or"],"type":"string"},"name":{"$ref":"#/components/schemas/TextFilterValue"},"totalDocuments":{"$ref":"#/components/schemas/NumericFilterValue"}},"type":"object"},"pagination":{"$ref":"#/components/schemas/Pagination"},"sort":{"items":{"properties":{"field":{"enum":["name","totalDocuments"],"type":"string"},"order":{"$ref":"#/components/schemas/SortOrder"}},"required":["field"],"type":"object"},"type":"array"}},"type":"object"},"LenderListResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/LenderSummary"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"LenderMatchMode":{"enum":["and","or"],"type":"string"},"LenderNormalization":{"properties":{"aliasCount":{"description":"Stored lender-name variants this id expands to","minimum":0,"type":"integer"},"displayName":{"nullable":true,"type":"string"},"id":{"description":"Canonical lender-dictionary id, or null","nullable":true,"type":"string"},"matchedVia":{"description":"`id` = the value already WAS a canonical key; `alias` = a stored lender name; `name` = matched the display/canonical name; `unresolved` = fell back to raw text match; `degraded` = the dictionary could not be consulted.","enum":["id","alias","name","unresolved","degraded"],"type":"string"},"original":{"description":"The value the caller sent","type":"string"},"totalDocuments":{"description":"Loans the dictionary attributes to this id. A small number next to a well-known lender name means the name matched a minor entry.","minimum":0,"type":"integer"}},"required":["original","id","displayName","matchedVia","aliasCount","totalDocuments"],"type":"object"},"LenderSummary":{"properties":{"canonicalName":{"nullable":true,"type":"string"},"displayName":{"nullable":true,"type":"string"},"id":{"type":"string"},"totalDocuments":{"nullable":true,"type":"number"}},"required":["id"],"type":"object"},"LoanBorrowerStatusFilterValue":{"anyOf":[{"description":"One of (case-insensitive): Current, PSALE, PWNLO, PWCLO, C_PWNLO, C_PWCLO, R_CWNLO, R_CWCLO, E_CWNLO, E_CWCLO, REO_CWNLO, REO_CWCLO, UNK_NOORIG, UNK_PWNLO, UNK_PWCLO","enum":["Current","PSALE","PWNLO","PWCLO","C_PWNLO","C_PWCLO","R_CWNLO","R_CWCLO","E_CWNLO","E_CWCLO","REO_CWNLO","REO_CWCLO","UNK_NOORIG","UNK_PWNLO","UNK_PWCLO"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): Current, PSALE, PWNLO, PWCLO, C_PWNLO, C_PWCLO, R_CWNLO, R_CWCLO, E_CWNLO, E_CWCLO, REO_CWNLO, REO_CWCLO, UNK_NOORIG, UNK_PWNLO, UNK_PWCLO","enum":["Current","PSALE","PWNLO","PWCLO","C_PWNLO","C_PWCLO","R_CWNLO","R_CWCLO","E_CWNLO","E_CWCLO","REO_CWNLO","REO_CWCLO","UNK_NOORIG","UNK_PWNLO","UNK_PWCLO"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}],"description":"ModelMatch-derived loan position: whether the borrower on THIS loan is still the property's current owner. Codes read as [purpose_](C|P)W(N|C)LO — CW = current owner, PW = previous owner; NLO = a different originator than the prior loan, CLO = the same one (the retention signal).\n\nCURRENT OWNER — `Current` (no newer loan), `R_CWCLO`/`R_CWNLO` (refinanced), `E_CWCLO`/`E_CWNLO` (took equity). For \"past clients still in the home\" pass ALL FIVE: `\"Current\"` on its own silently drops ~5M loans whose borrower is still there but has since refinanced or tapped equity.\n\nPREVIOUS OWNER — `PSALE` (home sold), `PWCLO`/`PWNLO` (purchase loan), `C_PWCLO`/`C_PWNLO` (construction loan).\n\nUNKNOWN — `UNK_NOORIG` (the property's most recent loan had no originator; ~64% of all populated values), `UNK_PWCLO`/`UNK_PWNLO` (most recent loan was not a purchase). `REO_CWNLO`/`REO_CWCLO` exist but are vanishingly rare (<300 loans total) and are not classified in the source glossary.\n\nOnly ~69% of loans carry any status, so an absent value means unknown — not \"not current\"."},"LoanChartRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"borrowerStatus":{"$ref":"#/components/schemas/LoanBorrowerStatusFilterValue"},"broker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Broker shop NMLS id (digits only). A broker is a company — resolve a broker name to its NMLS id via instantSearch (or listCompanies)."}]},"buyerEntityType":{"$ref":"#/components/schemas/BooleanFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"conforming":{"$ref":"#/components/schemas/BooleanFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County name (e.g. \"Broward\") or 5-digit FIPS code. Names resolve to FIPS server-side; include a `state` filter to disambiguate."}]},"currentBalance":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated remaining principal balance (~19% populated). Approximate current equity as `homeValue` (AVM) minus this."}]},"employer":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Employer/company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Point-in-time equity recorded on the loan (sparse, ~10%). NOT a live current-equity figure. For HELOC/cash-out targeting on up-to-date equity, use properties search (listProperties) instead — its equity is far better populated and current."}]},"excludeBroker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans brokered by this broker-shop NMLS id (digits only) — the inverse of `broker`."}]},"excludeCity":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this city — the inverse of `city`."}]},"excludeLender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans from this lender ID (\"everyone but X\") — the inverse of `lender`, same id contract (resolve via instantSearch/listLenders). Loans with no lender stay in the results."}]},"excludeLoanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans funded by this company NMLS id (digits only) — the inverse of `loanCompany`."}]},"excludeOriginator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans with this originator NMLS id (digits only) — the inverse of `originator`. Common for 'everyone but my own shop' lists."}]},"excludeState":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this state (2-letter code, e.g. \"CA\") — the inverse of `state`. For \"everywhere but this state\" lists."}]},"excludeZipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this ZIP code — the inverse of `zipCode`."}]},"fips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exact 5-digit county FIPS code (no name resolution) — the code-only escape hatch alongside `county`."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"homeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"AVM (automated valuation) at the linked property (~26%, MLS-linked). Pair with `currentBalance` to approximate current equity."}]},"includeUnknownOriginator":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Include loans that have no originator NMLS id. Omitted/false (default): such loans are excluded — the vast majority are pre-2016 public records with no linkable originator. true: include them. Note that the default scopes results to loans with a known originator (~2016+ recordings)."}]},"interestRate":{"$ref":"#/components/schemas/NumericFilterValue"},"lender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender ID — the normalized lender-dictionary key, NOT a fuzzy name match. Resolve a lender via instantSearch (or listLenders) and pass the `id` it returns (e.g. \"mortgage_rocket\" or \"mortgage rocket\"). Underscores and letter case are normalized, so either id surface works. A stored normalized lender name (what the `slice: \"lender\"` chart buckets emit) is also accepted, so a chart bucket key filters directly. A value that is neither returns 400 rather than silently matching nothing — to search by lender NAME, use `lenderName`."}]},"lenderName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender name as recorded on the loan document — fuzzy, all-terms match (e.g. \"Fifth Third\"). The name counterpart to the exact-id `lender` filter; use `lender` when you have a resolved id, and this when you only have a name."}]},"loanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Funding/loan company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"loanType":{"$ref":"#/components/schemas/LoanTypeFilterValue"},"ltvAtOrigination":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan-to-value at ORIGINATION (sparse). This is not a current LTV — there is no stored current-LTV field on loans."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"mortgageDate":{"$ref":"#/components/schemas/DateFilterValue"},"originator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Loan originator NMLS id (digits only). To search by name use `originatorName`, or resolve a name to its id via instantSearch."}]},"originatorName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (same originator can return wildly different counts by name string). Resolve the loan officer via instantSearch and filter by `originator` (exact NMLS id) instead. Still functional for now."}]},"saleDate":{"$ref":"#/components/schemas/DateFilterValue"},"salePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"transactionType":{"$ref":"#/components/schemas/LoanTransactionTypeFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zipCode` — same ZIP filter, accepted for cross-entity key parity."}]},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"measure":{"$ref":"#/components/schemas/ChartMeasure"},"period":{"$ref":"#/components/schemas/Period"},"slice":{"$ref":"#/components/schemas/LoanSlice"}},"required":["slice"],"type":"object"},"LoanDetail":{"allOf":[{"$ref":"#/components/schemas/LoanSummary"},{"properties":{"buyers":{"items":{"nullable":true},"nullable":true,"type":"array"},"downPayment":{"nullable":true},"employersAtTimeOfLoan":{"items":{"type":"string"},"nullable":true,"type":"array"},"equity":{"nullable":true,"type":"number"},"estimatedPayment":{"nullable":true,"type":"number"},"homeValue":{"nullable":true,"type":"number"},"listAgent":{"nullable":true},"loanTermMonths":{"nullable":true,"type":"number"},"ltv":{"nullable":true,"type":"number"},"mmSaleId":{"nullable":true,"type":"string"},"propertyUseCode":{"nullable":true,"type":"string"},"recordingDate":{"nullable":true,"type":"string"},"sellers":{"items":{"nullable":true},"nullable":true,"type":"array"},"soldAgent":{"nullable":true},"titleCompany":{"nullable":true}},"type":"object"}]},"LoanDetailResponse":{"properties":{"data":{"$ref":"#/components/schemas/LoanDetail"}},"required":["data"],"type":"object"},"LoanListRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"borrowerStatus":{"$ref":"#/components/schemas/LoanBorrowerStatusFilterValue"},"broker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Broker shop NMLS id (digits only). A broker is a company — resolve a broker name to its NMLS id via instantSearch (or listCompanies)."}]},"buyerEntityType":{"$ref":"#/components/schemas/BooleanFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"conforming":{"$ref":"#/components/schemas/BooleanFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County name (e.g. \"Broward\") or 5-digit FIPS code. Names resolve to FIPS server-side; include a `state` filter to disambiguate."}]},"currentBalance":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated remaining principal balance (~19% populated). Approximate current equity as `homeValue` (AVM) minus this."}]},"employer":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Employer/company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Point-in-time equity recorded on the loan (sparse, ~10%). NOT a live current-equity figure. For HELOC/cash-out targeting on up-to-date equity, use properties search (listProperties) instead — its equity is far better populated and current."}]},"excludeBroker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans brokered by this broker-shop NMLS id (digits only) — the inverse of `broker`."}]},"excludeCity":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this city — the inverse of `city`."}]},"excludeLender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans from this lender ID (\"everyone but X\") — the inverse of `lender`, same id contract (resolve via instantSearch/listLenders). Loans with no lender stay in the results."}]},"excludeLoanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans funded by this company NMLS id (digits only) — the inverse of `loanCompany`."}]},"excludeOriginator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans with this originator NMLS id (digits only) — the inverse of `originator`. Common for 'everyone but my own shop' lists."}]},"excludeState":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this state (2-letter code, e.g. \"CA\") — the inverse of `state`. For \"everywhere but this state\" lists."}]},"excludeZipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this ZIP code — the inverse of `zipCode`."}]},"fips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exact 5-digit county FIPS code (no name resolution) — the code-only escape hatch alongside `county`."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"homeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"AVM (automated valuation) at the linked property (~26%, MLS-linked). Pair with `currentBalance` to approximate current equity."}]},"includeUnknownOriginator":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Include loans that have no originator NMLS id. Omitted/false (default): such loans are excluded — the vast majority are pre-2016 public records with no linkable originator. true: include them. Note that the default scopes results to loans with a known originator (~2016+ recordings)."}]},"interestRate":{"$ref":"#/components/schemas/NumericFilterValue"},"lender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender ID — the normalized lender-dictionary key, NOT a fuzzy name match. Resolve a lender via instantSearch (or listLenders) and pass the `id` it returns (e.g. \"mortgage_rocket\" or \"mortgage rocket\"). Underscores and letter case are normalized, so either id surface works. A stored normalized lender name (what the `slice: \"lender\"` chart buckets emit) is also accepted, so a chart bucket key filters directly. A value that is neither returns 400 rather than silently matching nothing — to search by lender NAME, use `lenderName`."}]},"lenderName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender name as recorded on the loan document — fuzzy, all-terms match (e.g. \"Fifth Third\"). The name counterpart to the exact-id `lender` filter; use `lender` when you have a resolved id, and this when you only have a name."}]},"loanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Funding/loan company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"loanType":{"$ref":"#/components/schemas/LoanTypeFilterValue"},"ltvAtOrigination":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan-to-value at ORIGINATION (sparse). This is not a current LTV — there is no stored current-LTV field on loans."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"mortgageDate":{"$ref":"#/components/schemas/DateFilterValue"},"originator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Loan originator NMLS id (digits only). To search by name use `originatorName`, or resolve a name to its id via instantSearch."}]},"originatorName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (same originator can return wildly different counts by name string). Resolve the loan officer via instantSearch and filter by `originator` (exact NMLS id) instead. Still functional for now."}]},"saleDate":{"$ref":"#/components/schemas/DateFilterValue"},"salePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"transactionType":{"$ref":"#/components/schemas/LoanTransactionTypeFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zipCode` — same ZIP filter, accepted for cross-entity key parity."}]},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"pagination":{"$ref":"#/components/schemas/Pagination"},"period":{"$ref":"#/components/schemas/Period"},"sort":{"items":{"properties":{"field":{"enum":["city","state","zipCode","county","transactionType","loanType","conforming","mortgageAmount","mortgageDate","broker","loanCompany","lender","borrowerStatus","salePrice","saleDate","originator","originatorName","interestRate","equity","homeValue","ltvAtOrigination","currentBalance"],"type":"string"},"order":{"$ref":"#/components/schemas/SortOrder"}},"required":["field"],"type":"object"},"type":"array"}},"type":"object"},"LoanListResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/LoanSummary"},"type":"array"},"lenderNormalizations":{"description":"How each `lenderName` value resolved against the lender dictionary. Present when a `lenderName` filter was supplied.","items":{"$ref":"#/components/schemas/LenderNormalization"},"type":"array"},"locationNormalizations":{"description":"How each location filter value resolved. Present when a `city`/`county`/`state`/`zip` filter was supplied.","items":{"$ref":"#/components/schemas/LocationNormalization"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"LoanSlice":{"enum":["transactionType","loanType","city","county","state","zip","lender","broker","loanCompany","originator"],"type":"string"},"LoanSummary":{"properties":{"apn":{"nullable":true,"type":"string"},"borrowerName":{"nullable":true,"type":"string"},"borrowerStatus":{"enum":["Current","PSALE","PWNLO","PWCLO","C_PWNLO","C_PWCLO","R_CWNLO","R_CWCLO","E_CWNLO","E_CWCLO","REO_CWNLO","REO_CWCLO","UNK_NOORIG","UNK_PWNLO","UNK_PWCLO",null],"nullable":true,"type":"string"},"brokerNmlsId":{"nullable":true,"type":"string"},"city":{"nullable":true,"type":"string"},"companyName":{"nullable":true,"type":"string"},"companyNmlsId":{"nullable":true,"type":"string"},"conforming":{"nullable":true,"type":"boolean"},"coordinates":{"nullable":true,"properties":{"lat":{"type":"number"},"lon":{"type":"number"}},"required":["lat","lon"],"type":"object"},"fips":{"nullable":true,"type":"string"},"id":{"type":"string"},"interestRate":{"nullable":true,"type":"number"},"lenderName":{"nullable":true,"type":"string"},"listPrice":{"nullable":true,"type":"number"},"loanType":{"nullable":true,"type":"string"},"mmPropertyId":{"nullable":true,"type":"string"},"mortgageAmount":{"nullable":true,"type":"number"},"mortgageDate":{"nullable":true,"type":"string"},"originatorEmail":{"deprecated":true,"description":"DEPRECATED — ALWAYS NULL. Loan records carry no originator email field, so this is null on every loan; it is retained only for response-shape compatibility. To get a loan officer's email, take `originatorNmlsId` from this response and fetch the originator (`GET /originators/{nmlsId}`), whose `email` field carries it — available for roughly 14% of loan officers.","nullable":true,"type":"string"},"originatorName":{"nullable":true,"type":"string"},"originatorNmlsId":{"nullable":true,"type":"string"},"salePrice":{"nullable":true,"type":"number"},"sellerName":{"nullable":true,"type":"string"},"state":{"nullable":true,"type":"string"},"streetAddress":{"nullable":true,"type":"string"},"transactionDate":{"nullable":true,"type":"string"},"transactionType":{"nullable":true,"type":"string"},"zipCode":{"nullable":true,"type":"string"}},"required":["id"],"type":"object"},"LoanSummaryRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"borrowerStatus":{"$ref":"#/components/schemas/LoanBorrowerStatusFilterValue"},"broker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Broker shop NMLS id (digits only). A broker is a company — resolve a broker name to its NMLS id via instantSearch (or listCompanies)."}]},"buyerEntityType":{"$ref":"#/components/schemas/BooleanFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"conforming":{"$ref":"#/components/schemas/BooleanFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County name (e.g. \"Broward\") or 5-digit FIPS code. Names resolve to FIPS server-side; include a `state` filter to disambiguate."}]},"currentBalance":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated remaining principal balance (~19% populated). Approximate current equity as `homeValue` (AVM) minus this."}]},"employer":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Employer/company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Point-in-time equity recorded on the loan (sparse, ~10%). NOT a live current-equity figure. For HELOC/cash-out targeting on up-to-date equity, use properties search (listProperties) instead — its equity is far better populated and current."}]},"excludeBroker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans brokered by this broker-shop NMLS id (digits only) — the inverse of `broker`."}]},"excludeCity":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this city — the inverse of `city`."}]},"excludeLender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans from this lender ID (\"everyone but X\") — the inverse of `lender`, same id contract (resolve via instantSearch/listLenders). Loans with no lender stay in the results."}]},"excludeLoanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans funded by this company NMLS id (digits only) — the inverse of `loanCompany`."}]},"excludeOriginator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans with this originator NMLS id (digits only) — the inverse of `originator`. Common for 'everyone but my own shop' lists."}]},"excludeState":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this state (2-letter code, e.g. \"CA\") — the inverse of `state`. For \"everywhere but this state\" lists."}]},"excludeZipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this ZIP code — the inverse of `zipCode`."}]},"fips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exact 5-digit county FIPS code (no name resolution) — the code-only escape hatch alongside `county`."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"homeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"AVM (automated valuation) at the linked property (~26%, MLS-linked). Pair with `currentBalance` to approximate current equity."}]},"includeUnknownOriginator":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Include loans that have no originator NMLS id. Omitted/false (default): such loans are excluded — the vast majority are pre-2016 public records with no linkable originator. true: include them. Note that the default scopes results to loans with a known originator (~2016+ recordings)."}]},"interestRate":{"$ref":"#/components/schemas/NumericFilterValue"},"lender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender ID — the normalized lender-dictionary key, NOT a fuzzy name match. Resolve a lender via instantSearch (or listLenders) and pass the `id` it returns (e.g. \"mortgage_rocket\" or \"mortgage rocket\"). Underscores and letter case are normalized, so either id surface works. A stored normalized lender name (what the `slice: \"lender\"` chart buckets emit) is also accepted, so a chart bucket key filters directly. A value that is neither returns 400 rather than silently matching nothing — to search by lender NAME, use `lenderName`."}]},"lenderName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender name as recorded on the loan document — fuzzy, all-terms match (e.g. \"Fifth Third\"). The name counterpart to the exact-id `lender` filter; use `lender` when you have a resolved id, and this when you only have a name."}]},"loanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Funding/loan company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"loanType":{"$ref":"#/components/schemas/LoanTypeFilterValue"},"ltvAtOrigination":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan-to-value at ORIGINATION (sparse). This is not a current LTV — there is no stored current-LTV field on loans."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"mortgageDate":{"$ref":"#/components/schemas/DateFilterValue"},"originator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Loan originator NMLS id (digits only). To search by name use `originatorName`, or resolve a name to its id via instantSearch."}]},"originatorName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (same originator can return wildly different counts by name string). Resolve the loan officer via instantSearch and filter by `originator` (exact NMLS id) instead. Still functional for now."}]},"saleDate":{"$ref":"#/components/schemas/DateFilterValue"},"salePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"transactionType":{"$ref":"#/components/schemas/LoanTransactionTypeFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zipCode` — same ZIP filter, accepted for cross-entity key parity."}]},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"period":{"$ref":"#/components/schemas/Period"}},"type":"object"},"LoanTimeSeriesRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"borrowerStatus":{"$ref":"#/components/schemas/LoanBorrowerStatusFilterValue"},"broker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Broker shop NMLS id (digits only). A broker is a company — resolve a broker name to its NMLS id via instantSearch (or listCompanies)."}]},"buyerEntityType":{"$ref":"#/components/schemas/BooleanFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"conforming":{"$ref":"#/components/schemas/BooleanFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County name (e.g. \"Broward\") or 5-digit FIPS code. Names resolve to FIPS server-side; include a `state` filter to disambiguate."}]},"currentBalance":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated remaining principal balance (~19% populated). Approximate current equity as `homeValue` (AVM) minus this."}]},"employer":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Employer/company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Point-in-time equity recorded on the loan (sparse, ~10%). NOT a live current-equity figure. For HELOC/cash-out targeting on up-to-date equity, use properties search (listProperties) instead — its equity is far better populated and current."}]},"excludeBroker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans brokered by this broker-shop NMLS id (digits only) — the inverse of `broker`."}]},"excludeCity":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this city — the inverse of `city`."}]},"excludeLender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans from this lender ID (\"everyone but X\") — the inverse of `lender`, same id contract (resolve via instantSearch/listLenders). Loans with no lender stay in the results."}]},"excludeLoanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans funded by this company NMLS id (digits only) — the inverse of `loanCompany`."}]},"excludeOriginator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans with this originator NMLS id (digits only) — the inverse of `originator`. Common for 'everyone but my own shop' lists."}]},"excludeState":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this state (2-letter code, e.g. \"CA\") — the inverse of `state`. For \"everywhere but this state\" lists."}]},"excludeZipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this ZIP code — the inverse of `zipCode`."}]},"fips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exact 5-digit county FIPS code (no name resolution) — the code-only escape hatch alongside `county`."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"homeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"AVM (automated valuation) at the linked property (~26%, MLS-linked). Pair with `currentBalance` to approximate current equity."}]},"includeUnknownOriginator":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Include loans that have no originator NMLS id. Omitted/false (default): such loans are excluded — the vast majority are pre-2016 public records with no linkable originator. true: include them. Note that the default scopes results to loans with a known originator (~2016+ recordings)."}]},"interestRate":{"$ref":"#/components/schemas/NumericFilterValue"},"lender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender ID — the normalized lender-dictionary key, NOT a fuzzy name match. Resolve a lender via instantSearch (or listLenders) and pass the `id` it returns (e.g. \"mortgage_rocket\" or \"mortgage rocket\"). Underscores and letter case are normalized, so either id surface works. A stored normalized lender name (what the `slice: \"lender\"` chart buckets emit) is also accepted, so a chart bucket key filters directly. A value that is neither returns 400 rather than silently matching nothing — to search by lender NAME, use `lenderName`."}]},"lenderName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender name as recorded on the loan document — fuzzy, all-terms match (e.g. \"Fifth Third\"). The name counterpart to the exact-id `lender` filter; use `lender` when you have a resolved id, and this when you only have a name."}]},"loanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Funding/loan company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"loanType":{"$ref":"#/components/schemas/LoanTypeFilterValue"},"ltvAtOrigination":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan-to-value at ORIGINATION (sparse). This is not a current LTV — there is no stored current-LTV field on loans."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"mortgageDate":{"$ref":"#/components/schemas/DateFilterValue"},"originator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Loan originator NMLS id (digits only). To search by name use `originatorName`, or resolve a name to its id via instantSearch."}]},"originatorName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (same originator can return wildly different counts by name string). Resolve the loan officer via instantSearch and filter by `originator` (exact NMLS id) instead. Still functional for now."}]},"saleDate":{"$ref":"#/components/schemas/DateFilterValue"},"salePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"transactionType":{"$ref":"#/components/schemas/LoanTransactionTypeFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zipCode` — same ZIP filter, accepted for cross-entity key parity."}]},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"interval":{"$ref":"#/components/schemas/Interval"},"measure":{"$ref":"#/components/schemas/Measure"},"period":{"$ref":"#/components/schemas/Period"},"segment":{"$ref":"#/components/schemas/LoanSlice"}},"type":"object"},"LoanTransactionTypeFilterValue":{"anyOf":[{"description":"One of (case-insensitive): purchase, refinance, construction, equity, reo","enum":["purchase","refinance","construction","equity","reo"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): purchase, refinance, construction, equity, reo","enum":["purchase","refinance","construction","equity","reo"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"LoanTypeFilterValue":{"anyOf":[{"description":"One of (case-insensitive): conventional, fha, va, usda, he, heloc, building, balloon, commercial, reverse, sba, assumption, stand_alone_refi, stand_alone_second, aggregate, closed_end, negative_amortization, land_contract, modification, trade, other, unknown","enum":["conventional","fha","va","usda","he","heloc","building","balloon","commercial","reverse","sba","assumption","stand_alone_refi","stand_alone_second","aggregate","closed_end","negative_amortization","land_contract","modification","trade","other","unknown"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): conventional, fha, va, usda, he, heloc, building, balloon, commercial, reverse, sba, assumption, stand_alone_refi, stand_alone_second, aggregate, closed_end, negative_amortization, land_contract, modification, trade, other, unknown","enum":["conventional","fha","va","usda","he","heloc","building","balloon","commercial","reverse","sba","assumption","stand_alone_refi","stand_alone_second","aggregate","closed_end","negative_amortization","land_contract","modification","trade","other","unknown"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"LocationNormalization":{"properties":{"candidates":{"description":"Location ids matching an ambiguous name, ranked. Use `instantSearch` or `suggestLocations` to pick one.","items":{"type":"string"},"type":"array"},"confidence":{"description":"\"exact\" — matched a dictionary entry as written. \"normalized\" — resolved to a different spelling or merged several candidates. \"fallback\" — NOT resolved; the raw value was passed through, so a zero result means the name was not recognized rather than empty.","enum":["exact","normalized","fallback"],"example":"normalized","type":"string"},"displayName":{"example":"Saint Louis, MO","type":"string"},"field":{"description":"The filter key this applies to","example":"city","type":"string"},"id":{"description":"Resolved location id — pass this back for an exact filter","example":"city_mo_saint-louis","type":"string"},"normalized":{"example":"Saint Louis","type":"string"},"original":{"example":"St. Louis","type":"string"},"variants":{"description":"Spellings actually queried against the index","items":{"type":"string"},"type":"array"}},"required":["field","original","normalized","displayName","confidence"],"type":"object"},"LocationRetrieveResponse":{"properties":{"location":{"$ref":"#/components/schemas/NormalizedLocation"}},"required":["location"],"type":"object"},"LocationSuggestResponse":{"properties":{"suggestions":{"items":{"$ref":"#/components/schemas/MapboxSuggestion"},"type":"array"}},"required":["suggestions"],"type":"object"},"MapboxSuggestion":{"properties":{"feature_type":{"type":"string"},"full_address":{"type":"string"},"id":{"description":"Location dictionary id (e.g. `city_mo_saint-louis`). Pass this to a city / county filter. Absent on Mapbox address suggestions.","type":"string"},"mapbox_id":{"description":"Pass to `retrieveLocation`. On a dictionary suggestion this is the location `id`; on a Mapbox suggestion it is the Mapbox feature id.","type":"string"},"name":{"type":"string"},"place_formatted":{"type":"string"},"source":{"description":"Where the suggestion came from. `dictionary` suggestions carry an `id` that filters accept; `mapbox` suggestions are addresses and coordinates only.","enum":["dictionary","mapbox"],"type":"string"},"state":{"type":"string"},"totalCount":{"description":"Records across all entities at this location — a popularity signal for ranking, not a filter result count.","type":"number"},"type":{"description":"Location type — `city` or `county`.","type":"string"}},"required":["mapbox_id","name","feature_type"],"type":"object"},"MarketChartMeasure":{"default":"units","description":"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–1,000; `avgDTI` 0–1,000; `avgIncome` 0–100,000,000; `avgAppraisedValue` 0–100,000,000; `avgPurchasePrice` 0–100,000,000; `avgDtiFront` 0–1,000; `avgCombinedLtv` 0–1,000; `avgLoanTerm` 0–1,200; `originatedVolume` 0–100,000,000. `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 — while `originatedUnits` and `originatedVolume` cover originations only. Which metric each bar reports — and, with one exception, NOT what the bars are ranked by. Ranking is by transaction count unless you explicitly pass `volume`, which ranks by dollars instead. Defaults to `units`, so \"top originators\" means the busiest rather than the biggest. The average measures deliberately rank by count too: ordering a high-cardinality slice by its own mean returns whichever one-transaction buckets happened to score highest, so \"top zips by average rate\" would mean \"zips with one weird loan\" — ranked by count it means \"the busiest zips, with their rates\". Every bucket publishes its own `count`, so the sample size behind a value is never implicit.","enum":["volume","units","avgRate","avgLoanAmount","avgCreditScore","avgLTV","avgDTI","avgIncome","avgAppraisedValue","avgPurchasePrice","avgDtiFront","avgCombinedLtv","avgLoanTerm","originatedUnits","originatedVolume"],"type":"string"},"MarketChartRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/MarketFlatFilters"},"measure":{"$ref":"#/components/schemas/MarketChartMeasure"},"period":{"$ref":"#/components/schemas/Period"},"slice":{"$ref":"#/components/schemas/MarketSliceDimension"}},"required":["slice"],"type":"object"},"MarketCommunityBucket":{"properties":{"avgMinorityTractPct":{"description":"Average non-white share (0-100) of the neighborhood population across originations that carry it. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgTractIncomeVsMetroPct":{"description":"Average neighborhood median family income as a percent of its metro area's — 100 is parity, and it legitimately exceeds 100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"craEligibleCoverage":{"description":"Originations carrying a CRA-eligibility determination — the denominator of `craEligibleSharePct`. Effectively the whole population: the determination is loan-level and is present on every record.","type":"number"},"craEligibleOriginations":{"type":"number"},"craEligibleSharePct":{"description":"Share (0-100) of `craEligibleCoverage` that is CRA-eligible — a low- or moderate-income neighborhood OR a low- or moderate-income borrower. Null when nothing in scope carries the determination.","nullable":true,"type":"number"},"incomeBandCoverage":{"description":"Originations whose neighborhood carries an income band — the denominator of `lowModIncomeTractSharePct`, `middleIncomeTractSharePct` and every `incomeBands[].sharePct`. READ THIS FIRST: roughly a fifth of records carry a band, and a share taken over the full population instead is about 4.5x too low.","type":"number"},"incomeBands":{"items":{"$ref":"#/components/schemas/MarketCommunityIncomeBand"},"type":"array"},"key":{"description":"The dimension value this bucket covers — a metro (CBSA) code for `metro`, a state code for `state`, and so on.","type":"string"},"lowModIncomeTractOriginations":{"type":"number"},"lowModIncomeTractSharePct":{"description":"Share (0-100) of `incomeBandCoverage` originated in a low- or moderate-income neighborhood. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"majorityMinorityTractOriginations":{"type":"number"},"majorityMinorityTractSharePct":{"description":"Share (0-100) of `minorityTractCoverage` originated in a majority-minority neighborhood. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"middleIncomeTractOriginations":{"type":"number"},"middleIncomeTractSharePct":{"description":"Share (0-100) of `incomeBandCoverage` originated in a middle-income neighborhood. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"minorityTractCoverage":{"description":"Originations whose neighborhood carries the majority-minority determination — the denominator of `majorityMinorityTractSharePct` and the population behind `avgMinorityTractPct`. About half of all records; it is a different denominator from `incomeBandCoverage`.","type":"number"},"originations":{"description":"Originations matched by the filters in this scope.","type":"number"}},"required":["key","originations","craEligibleOriginations","craEligibleCoverage","craEligibleSharePct","incomeBandCoverage","lowModIncomeTractOriginations","lowModIncomeTractSharePct","middleIncomeTractOriginations","middleIncomeTractSharePct","incomeBands","majorityMinorityTractOriginations","minorityTractCoverage","majorityMinorityTractSharePct","avgMinorityTractPct","avgTractIncomeVsMetroPct"],"type":"object"},"MarketCommunityIncomeBand":{"description":"One FFIEC tract income band and its share (0-100) of `incomeBandCoverage`. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","properties":{"level":{"enum":["low","moderate","middle","upper"],"type":"string"},"originations":{"type":"number"},"sharePct":{"nullable":true,"type":"number"}},"required":["level","originations","sharePct"],"type":"object"},"MarketCommunityIncomeLevel":{"anyOf":[{"description":"One of (case-insensitive): low, moderate, middle, upper","enum":["low","moderate","middle","upper"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): low, moderate, middle, upper","enum":["low","moderate","middle","upper"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}],"description":"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."},"MarketCommunityLendingRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/MarketFlatFilters"},"limit":{"description":"Maximum buckets when `slice` is supplied (default 25, max 200).","maximum":200,"minimum":1,"type":"integer"},"period":{"$ref":"#/components/schemas/Period"},"slice":{"description":"Break the mix down by a market dimension — `metro` for the metro (CBSA) grain, `state` / `county` / `zip` for geography, or any product dimension. Each bucket reports its OWN denominators, so bucket shares are comparable to each other and to the overall mix. Omit for the overall mix only.","enum":["state","county","metro","zip","loanPurpose","loanType","propertyType","occupancyType","amortizationType","channel","borrowerGeneration","firstTimeHomebuyer","veteranIndicator","hmdaActionTaken","selfEmployed","currentHomeOwner"],"type":"string"}},"type":"object"},"MarketCommunityLendingResponse":{"properties":{"overall":{"$ref":"#/components/schemas/MarketCommunityMix"},"slice":{"properties":{"buckets":{"items":{"$ref":"#/components/schemas/MarketCommunityBucket"},"type":"array"},"dimension":{"type":"string"}},"required":["dimension","buckets"],"type":"object"}},"required":["overall"],"type":"object"},"MarketCommunityMix":{"properties":{"avgMinorityTractPct":{"description":"Average non-white share (0-100) of the neighborhood population across originations that carry it. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"avgTractIncomeVsMetroPct":{"description":"Average neighborhood median family income as a percent of its metro area's — 100 is parity, and it legitimately exceeds 100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"craEligibleCoverage":{"description":"Originations carrying a CRA-eligibility determination — the denominator of `craEligibleSharePct`. Effectively the whole population: the determination is loan-level and is present on every record.","type":"number"},"craEligibleOriginations":{"type":"number"},"craEligibleSharePct":{"description":"Share (0-100) of `craEligibleCoverage` that is CRA-eligible — a low- or moderate-income neighborhood OR a low- or moderate-income borrower. Null when nothing in scope carries the determination.","nullable":true,"type":"number"},"incomeBandCoverage":{"description":"Originations whose neighborhood carries an income band — the denominator of `lowModIncomeTractSharePct`, `middleIncomeTractSharePct` and every `incomeBands[].sharePct`. READ THIS FIRST: roughly a fifth of records carry a band, and a share taken over the full population instead is about 4.5x too low.","type":"number"},"incomeBands":{"items":{"$ref":"#/components/schemas/MarketCommunityIncomeBand"},"type":"array"},"lowModIncomeTractOriginations":{"type":"number"},"lowModIncomeTractSharePct":{"description":"Share (0-100) of `incomeBandCoverage` originated in a low- or moderate-income neighborhood. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"majorityMinorityTractOriginations":{"type":"number"},"majorityMinorityTractSharePct":{"description":"Share (0-100) of `minorityTractCoverage` originated in a majority-minority neighborhood. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"middleIncomeTractOriginations":{"type":"number"},"middleIncomeTractSharePct":{"description":"Share (0-100) of `incomeBandCoverage` originated in a middle-income neighborhood. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"minorityTractCoverage":{"description":"Originations whose neighborhood carries the majority-minority determination — the denominator of `majorityMinorityTractSharePct` and the population behind `avgMinorityTractPct`. About half of all records; it is a different denominator from `incomeBandCoverage`.","type":"number"},"originations":{"description":"Originations matched by the filters in this scope.","type":"number"}},"required":["originations","craEligibleOriginations","craEligibleCoverage","craEligibleSharePct","incomeBandCoverage","lowModIncomeTractOriginations","lowModIncomeTractSharePct","middleIncomeTractOriginations","middleIncomeTractSharePct","incomeBands","majorityMinorityTractOriginations","minorityTractCoverage","majorityMinorityTractSharePct","avgMinorityTractPct","avgTractIncomeVsMetroPct"],"type":"object"},"MarketConcentrationFilterValue":{"additionalProperties":false,"description":"Share of the originator's period volume held by their SINGLE LARGEST city, as a 0–100 percent. `{gte:50}` = 'at least half their book is in one city'. LOWER BOUNDS ONLY (`gte`/`gt`): an upper bound on this reads as 'some market is small', which is true of almost everyone — to find diversified producers use `marketCount` instead.","properties":{"gt":{"maximum":100,"minimum":0,"type":"number"},"gte":{"maximum":100,"minimum":0,"type":"number"},"lt":{"maximum":100,"minimum":0,"type":"number"},"lte":{"maximum":100,"minimum":0,"type":"number"}},"type":"object"},"MarketExcludedCounts":{"description":"Per-measure count of documents this query's sentinel guard excluded — documents that carry the measure's field but whose value is an out-of-range fill. Compare against `units` to see what share of the matched population each average was actually computed over. Absent for `units` (a document count, not a guarded metric).","properties":{"avgAppraisedValue":{"type":"number"},"avgCombinedLtv":{"type":"number"},"avgCreditScore":{"type":"number"},"avgDTI":{"type":"number"},"avgDtiFront":{"type":"number"},"avgIncome":{"type":"number"},"avgLTV":{"type":"number"},"avgLoanAmount":{"type":"number"},"avgLoanTerm":{"type":"number"},"avgPurchasePrice":{"type":"number"},"avgRate":{"type":"number"},"originatedVolume":{"type":"number"},"volume":{"type":"number"}},"type":"object"},"MarketField":{"enum":["state","county","zip","closingDate","loanPurpose","loanType","propertyType","occupancyType","amortizationType","channel","noteRate","loanAmount","creditScore","ltv","dti","income","appraisedValue","purchasePrice","combinedLtv","dtifront","loanTerm","hmdaActionTaken","loanApplicationDate"],"type":"string"},"MarketFlatFilters":{"additionalProperties":false,"properties":{"amortizationType":{"$ref":"#/components/schemas/TextFilterValue"},"appraisedValue":{"$ref":"#/components/schemas/NumericFilterValue"},"channel":{"$ref":"#/components/schemas/TextFilterValue"},"closingDate":{"$ref":"#/components/schemas/DateFilterValue"},"combinedLtv":{"$ref":"#/components/schemas/NumericFilterValue"},"communityIncomeLevel":{"$ref":"#/components/schemas/MarketCommunityIncomeLevel"},"county":{"$ref":"#/components/schemas/TextFilterValue"},"countyCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"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."}]},"craEligible":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Only CRA-eligible originations (a low- or moderate-income neighborhood OR a low- or moderate-income borrower). Determined on every origination."}]},"creditScore":{"$ref":"#/components/schemas/NumericFilterValue"},"dti":{"$ref":"#/components/schemas/NumericFilterValue"},"dtifront":{"$ref":"#/components/schemas/NumericFilterValue"},"hmdaActionTaken":{"$ref":"#/components/schemas/TextFilterValue"},"income":{"$ref":"#/components/schemas/NumericFilterValue"},"loanAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"loanApplicationDate":{"$ref":"#/components/schemas/DateFilterValue"},"loanPurpose":{"$ref":"#/components/schemas/TextFilterValue"},"loanTerm":{"$ref":"#/components/schemas/NumericFilterValue"},"loanType":{"$ref":"#/components/schemas/TextFilterValue"},"lowModIncomeTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"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."}]},"ltv":{"$ref":"#/components/schemas/NumericFilterValue"},"majorityMinorityTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"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."}]},"metro":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"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."}]},"middleIncomeTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Only originations in a middle-income neighborhood. Tract-level aggregate, never an individual attribute. Same caveat on `false` as `lowModIncomeTract`."}]},"minorityTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Non-white share (0-100) of the neighborhood's population. Tract-level aggregate, never an individual attribute."}]},"mode":{"enum":["and","or"],"type":"string"},"noteRate":{"$ref":"#/components/schemas/NumericFilterValue"},"occupancyType":{"$ref":"#/components/schemas/TextFilterValue"},"propertyType":{"$ref":"#/components/schemas/TextFilterValue"},"purchasePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"tractIncomeVsMetroPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"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."}]},"zip":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"MarketListRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/MarketFlatFilters"},"pagination":{"$ref":"#/components/schemas/Pagination"},"period":{"$ref":"#/components/schemas/Period"},"sort":{"items":{"properties":{"field":{"$ref":"#/components/schemas/MarketField"},"order":{"$ref":"#/components/schemas/SortOrder"}},"required":["field"],"type":"object"},"type":"array"}},"type":"object"},"MarketListResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/MarketRecord"},"type":"array"},"locationNormalizations":{"description":"How each location filter value resolved. Present when a `city`/`county`/`state`/`zip` filter was supplied.","items":{"$ref":"#/components/schemas/LocationNormalization"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"MarketMeasure":{"description":"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–1,000; `avgDTI` 0–1,000; `avgIncome` 0–100,000,000; `avgAppraisedValue` 0–100,000,000; `avgPurchasePrice` 0–100,000,000; `avgDtiFront` 0–1,000; `avgCombinedLtv` 0–1,000; `avgLoanTerm` 0–1,200; `originatedVolume` 0–100,000,000. `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 — while `originatedUnits` and `originatedVolume` cover originations only.","enum":["volume","units","avgRate","avgLoanAmount","avgCreditScore","avgLTV","avgDTI","avgIncome","avgAppraisedValue","avgPurchasePrice","avgDtiFront","avgCombinedLtv","avgLoanTerm","originatedUnits","originatedVolume"],"type":"string"},"MarketMetrics":{"properties":{"avgAppraisedValue":{"description":"Average appraised property value. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","nullable":true,"type":"number"},"avgCombinedLtv":{"description":"Average combined LTV (including subordinate liens). Excludes values outside 0–1,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","nullable":true,"type":"number"},"avgCreditScore":{"description":"Average credit score. Excludes values outside 300–850 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","type":"number"},"avgDTI":{"description":"Average back-end DTI ratio. Excludes values outside 0–1,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","type":"number"},"avgDtiFront":{"description":"Average front-end DTI ratio. Excludes values outside 0–1,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","nullable":true,"type":"number"},"avgIncome":{"description":"Average household annual income. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","type":"number"},"avgLTV":{"description":"Average LTV ratio. Excludes values outside 0–1,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","type":"number"},"avgLoanAmount":{"description":"Average loan amount. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","type":"number"},"avgLoanTerm":{"description":"Average loan term in months. Excludes values outside 0–1,200 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","nullable":true,"type":"number"},"avgPurchasePrice":{"description":"Average purchase price. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","nullable":true,"type":"number"},"avgRate":{"description":"Average note rate. Excludes values outside 0–25 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","type":"number"},"excluded":{"$ref":"#/components/schemas/MarketExcludedCounts"},"originatedUnits":{"description":"Loans ORIGINATED — the subset of `units` whose `hmdaActionTaken` is \"loan originated\". This is the count most callers mean by \"number of loans\"","type":"number"},"originatedVolume":{"description":"Total dollar volume of ORIGINATED loans — the subset of `volume` whose `hmdaActionTaken` is \"loan originated\". Pair with `originatedUnits` for an originated average loan size. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","type":"number"},"outcomes":{"description":"How the matched applications split by outcome — a complete PARTITION of `units` and `volume`, so the two headline numbers can be reconciled against their parts without a second query. Roughly half of all rows are not originated loans and the share varies widely by geography, so no fixed correction ratio exists. Summary only: on the chart use `slice: \"hmdaActionTaken\"`, on the time-series `segment: \"hmdaActionTaken\"`.","items":{"$ref":"#/components/schemas/MarketOutcomeBucket"},"type":"array"},"units":{"description":"Loan APPLICATIONS matching the filters — every outcome, not just originations. Withdrawn, denied, closed-for-incompleteness and secondary-market purchases are all counted here; roughly half of all rows are not originated loans, and the originated share varies enough by geography that no fixed correction ratio exists. For originations use `originatedUnits`; `outcomes` reports the full breakdown, and `hmdaActionTaken` filters on it","type":"number"},"volume":{"description":"Total dollar volume of loan APPLICATIONS matching the filters — every outcome, on the same population as `units`, not just originations. For originated dollars use `originatedVolume`. `volume` ÷ `units` is an application average, not an originated average. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","type":"number"}},"required":["volume","units","avgRate","avgLoanAmount","avgCreditScore","avgLTV","avgDTI","avgIncome","avgAppraisedValue","avgPurchasePrice","avgDtiFront","avgCombinedLtv","avgLoanTerm","originatedUnits","originatedVolume"],"type":"object"},"MarketOutcomeBucket":{"properties":{"outcome":{"description":"The application outcome, exactly as stored — the same vocabulary the `hmdaActionTaken` filter accepts, so any bucket here can be reproduced as a filter. The empty-string bucket carries rows with no outcome recorded. One value is a leaked source header row and is not a real outcome.","type":"string"},"units":{"description":"Applications with this outcome. These sum to `units`.","type":"number"},"volume":{"description":"Dollar volume for this outcome. These sum to `volume`.","type":"number"}},"required":["outcome","units","volume"],"type":"object"},"MarketRecord":{"properties":{"amortizationType":{"nullable":true,"type":"string"},"appraisedValue":{"nullable":true,"type":"number"},"borrowerGeneration":{"nullable":true,"type":"string"},"channel":{"nullable":true,"type":"string"},"closingDate":{"nullable":true,"type":"string"},"combinedLtv":{"nullable":true,"type":"number"},"county":{"nullable":true,"type":"string"},"creditScore":{"nullable":true,"type":"number"},"currentHomeOwner":{"nullable":true,"type":"boolean"},"dti":{"nullable":true,"type":"number"},"dtifront":{"nullable":true,"type":"number"},"firstTimeHomebuyer":{"nullable":true,"type":"boolean"},"fundingDate":{"nullable":true,"type":"string"},"hmdaActionTaken":{"nullable":true,"type":"string"},"id":{"description":"Document ID","type":"string"},"income":{"nullable":true,"type":"number"},"loanAmount":{"nullable":true,"type":"number"},"loanApplicationDate":{"nullable":true,"type":"string"},"loanPurpose":{"nullable":true,"type":"string"},"loanTerm":{"nullable":true,"type":"number"},"loanType":{"nullable":true,"type":"string"},"ltv":{"nullable":true,"type":"number"},"noteRate":{"nullable":true,"type":"number"},"occupancyType":{"nullable":true,"type":"string"},"propertyType":{"nullable":true,"type":"string"},"purchasePrice":{"nullable":true,"type":"number"},"selfEmployed":{"nullable":true,"type":"boolean"},"state":{"nullable":true,"type":"string"},"veteranIndicator":{"nullable":true,"type":"boolean"},"zip":{"nullable":true,"type":"string"}},"required":["id"],"type":"object"},"MarketSliceDimension":{"enum":["state","county","metro","zip","loanPurpose","loanType","propertyType","occupancyType","amortizationType","channel","borrowerGeneration","firstTimeHomebuyer","veteranIndicator","hmdaActionTaken","selfEmployed","currentHomeOwner"],"type":"string"},"MarketSummaryRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/MarketFlatFilters"},"period":{"$ref":"#/components/schemas/Period"}},"type":"object"},"MarketSummaryResponse":{"properties":{"current":{"$ref":"#/components/schemas/MarketMetrics"},"previous":{"allOf":[{"$ref":"#/components/schemas/MarketMetrics"},{"nullable":true}]}},"required":["current","previous"],"type":"object"},"MarketTimeSeriesBucket":{"properties":{"date":{"type":"string"},"excluded":{"description":"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.","type":"number"},"measureValue":{"description":"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.","nullable":true,"type":"number"},"segments":{"items":{"$ref":"#/components/schemas/MarketTimeSeriesSegment"},"type":"array"},"units":{"description":"Number of loans","type":"number"},"volume":{"description":"Total loan volume in dollars","type":"number"}},"required":["date","volume","units","measureValue"],"type":"object"},"MarketTimeSeriesRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/MarketFlatFilters"},"interval":{"$ref":"#/components/schemas/Interval"},"measure":{"$ref":"#/components/schemas/MarketMeasure"},"period":{"$ref":"#/components/schemas/Period"},"segment":{"$ref":"#/components/schemas/MarketSliceDimension"}},"type":"object"},"MarketTimeSeriesResponse":{"properties":{"current":{"items":{"$ref":"#/components/schemas/MarketTimeSeriesBucket"},"type":"array"},"measure":{"description":"Echo of the measure `measureValue` reports, so a caller never has to infer which metric it is plotting.","type":"string"},"previous":{"items":{"$ref":"#/components/schemas/MarketTimeSeriesBucket"},"nullable":true,"type":"array"}},"required":["measure","current","previous"],"type":"object"},"MarketTimeSeriesSegment":{"properties":{"label":{"type":"string"},"measureValue":{"description":"This segment's value for the requested `measure`. Null when the segment has no in-bounds document for the measure's field.","nullable":true,"type":"number"},"units":{"type":"number"},"volume":{"type":"number"}},"required":["label","volume","units","measureValue"],"type":"object"},"MeAuth":{"properties":{"clientId":{"description":"OAuth client that minted the token, when applicable","nullable":true,"type":"string"},"method":{"description":"Which credential the API resolved this caller from","enum":["api-key","bearer","session","internal"],"type":"string"},"profileResolved":{"description":"Always true on a successful read; retained for compatibility now that every caller type resolves the full profile","type":"boolean"},"role":{"description":"Global user role","type":"string"},"scopes":{"description":"OAuth scopes on the bearer token; null for API-key / session callers","items":{"type":"string"},"nullable":true,"type":"array"}},"required":["method","role","profileResolved"],"type":"object"},"MeCreditAllowance":{"properties":{"perCycle":{"description":"Credits granted to each member per billing cycle","type":"number"},"unitPriceCents":{"description":"Price of one on-demand credit, in cents","type":"number"}},"required":["perCycle","unitPriceCents"],"type":"object"},"MeCreditBalance":{"properties":{"cycle":{"description":"Credits from the current subscription cycle allowance","type":"number"},"onDemand":{"description":"Purchased credits that do not expire with the cycle","type":"number"},"personal":{"description":"The user's personal (non-workspace) credit balance","type":"number"},"total":{"type":"number"}},"required":["cycle","onDemand","personal","total"],"type":"object"},"MeCreditUsage":{"properties":{"granted":{"type":"number"},"purchased":{"type":"number"},"spent":{"type":"number"},"spentByCategory":{"properties":{"ai_agent":{"type":"number"},"ai_chat":{"type":"number"},"api":{"type":"number"},"enrichment":{"type":"number"}},"required":["api","enrichment","ai_chat","ai_agent"],"type":"object"},"window":{"properties":{"endDate":{"description":"ISO-8601, inclusive","type":"string"},"startDate":{"description":"ISO-8601, inclusive","type":"string"}},"required":["startDate","endDate"],"type":"object"}},"required":["window","granted","purchased","spent","spentByCategory"],"type":"object"},"MeCreditsResponse":{"properties":{"allowance":{"$ref":"#/components/schemas/MeCreditAllowance"},"balance":{"$ref":"#/components/schemas/MeCreditBalance"},"organizationId":{"type":"string"},"usage":{"$ref":"#/components/schemas/MeCreditUsage"}},"required":["organizationId","balance","allowance","usage"],"type":"object"},"MeOrganization":{"nullable":true,"properties":{"id":{"type":"string"},"role":{"description":"The caller's MEMBERSHIP role in this org (owner/admin/member)","nullable":true,"type":"string"}},"required":["id"],"type":"object"},"MePlan":{"nullable":true,"properties":{"displayName":{"nullable":true,"type":"string"},"group":{"nullable":true,"type":"string"},"id":{"type":"string"},"limits":{"additionalProperties":{"nullable":true},"description":"Plan limit map as configured in auth (free-form)","type":"object"},"name":{"type":"string"}},"required":["id","name","limits"],"type":"object"},"MePlanGrants":{"properties":{"organization":{"items":{"properties":{"additive":{"nullable":true,"type":"boolean"},"planId":{"type":"string"}},"required":["planId"],"type":"object"},"type":"array"},"user":{"items":{"properties":{"planId":{"type":"string"}},"required":["planId"],"type":"object"},"type":"array"}},"required":["organization","user"],"type":"object"},"MePlanResponse":{"properties":{"grants":{"$ref":"#/components/schemas/MePlanGrants"},"organizationId":{"type":"string"},"plan":{"$ref":"#/components/schemas/MePlan"},"subscription":{"$ref":"#/components/schemas/MeSubscription"}},"required":["organizationId","plan","subscription","grants"],"type":"object"},"MeResponse":{"properties":{"auth":{"$ref":"#/components/schemas/MeAuth"},"organization":{"$ref":"#/components/schemas/MeOrganization"},"user":{"$ref":"#/components/schemas/MeUser"}},"required":["user","organization","auth"],"type":"object"},"MeSubscription":{"nullable":true,"properties":{"planName":{"nullable":true,"type":"string"},"status":{"description":"active | trialing | past_due","type":"string"}},"required":["status"],"type":"object"},"MeTheme":{"enum":["light","dark","system"],"type":"string"},"MeUpdateRequest":{"additionalProperties":false,"properties":{"addressLine1":{"maxLength":255,"nullable":true,"type":"string"},"agentPhotoUrl":{"maxLength":4096,"nullable":true,"type":"string"},"city":{"maxLength":255,"nullable":true,"type":"string"},"contactCardType":{"$ref":"#/components/schemas/ContactCardType"},"contactPhone":{"maxLength":64,"nullable":true,"type":"string"},"headline":{"maxLength":255,"nullable":true,"type":"string"},"image":{"maxLength":4096,"nullable":true,"type":"string"},"jobRole":{"maxLength":255,"nullable":true,"type":"string"},"name":{"maxLength":255,"minLength":1,"type":"string"},"nmlsId":{"maxLength":64,"nullable":true,"type":"string"},"postalCode":{"maxLength":10,"nullable":true,"type":"string"},"qrBaseUrl":{"maxLength":4096,"nullable":true,"type":"string"},"reLicenseNumber":{"maxLength":64,"nullable":true,"type":"string"},"reLicenseState":{"maxLength":2,"nullable":true,"type":"string"},"sendNewLoginEmail":{"type":"boolean"},"signatureImage":{"maxLength":4096,"nullable":true,"type":"string"},"state":{"maxLength":2,"nullable":true,"type":"string"},"tagline":{"maxLength":255,"nullable":true,"type":"string"},"theme":{"$ref":"#/components/schemas/MeTheme"}},"type":"object"},"MeUser":{"properties":{"addressLine1":{"nullable":true,"type":"string"},"agentPhotoUrl":{"nullable":true,"type":"string"},"city":{"nullable":true,"type":"string"},"contactCardType":{"nullable":true,"type":"string"},"contactPhone":{"nullable":true,"type":"string"},"createdAt":{"nullable":true,"type":"string"},"email":{"nullable":true,"type":"string"},"emailVerified":{"nullable":true,"type":"boolean"},"headline":{"nullable":true,"type":"string"},"id":{"description":"Auth user id","type":"string"},"image":{"nullable":true,"type":"string"},"jobRole":{"nullable":true,"type":"string"},"name":{"nullable":true,"type":"string"},"nmlsId":{"nullable":true,"type":"string"},"postalCode":{"nullable":true,"type":"string"},"qrBaseUrl":{"nullable":true,"type":"string"},"reLicenseNumber":{"nullable":true,"type":"string"},"reLicenseState":{"nullable":true,"type":"string"},"sendNewLoginEmail":{"nullable":true,"type":"boolean"},"signatureImage":{"nullable":true,"type":"string"},"state":{"nullable":true,"type":"string"},"tagline":{"nullable":true,"type":"string"},"theme":{"nullable":true,"type":"string"}},"required":["id"],"type":"object"},"Measure":{"enum":["volume","units","avgSalePrice","avgListPrice"],"type":"string"},"MeiliUnavailable":{"properties":{"error":{"type":"string"}},"required":["error"],"type":"object"},"MlsStatus":{"enum":["SLD","ACT","PND","Cancelled","WDN","EXP","CNT","OFF","UNK","RNTD","RNT","LSE","RNT-SLD","RNT-ACT","RNT-PND","RNT-WDN","RNT-EXP","RNT-LSE","RNT-RNTD"],"type":"string"},"NormalizedLocation":{"nullable":true,"properties":{"city":{"type":"string"},"county":{"type":"string"},"displayName":{"type":"string"},"id":{"description":"Location dictionary id, when this location is one of ours. Pass it to a city / county filter instead of the free-text name.","type":"string"},"lat":{"type":"number"},"lon":{"type":"number"},"placeType":{"type":"string"},"state":{"type":"string"},"zip":{"type":"string"}},"required":["placeType","displayName"],"type":"object"},"NotFilter":{"properties":{"child":{"$ref":"#/components/schemas/FilterNode"},"type":{"enum":["not"],"type":"string"}},"required":["type","child"],"type":"object"},"NumericFilterValue":{"anyOf":[{"type":"number"},{"description":"Match any value","items":{"type":"number"},"type":"array"},{"description":"Numeric range. Excludes null/missing-field docs by default; add `includeNulls: true` to keep them.","properties":{"gt":{"type":"number"},"gte":{"type":"number"},"includeNulls":{"description":"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.","type":"boolean"},"lt":{"type":"number"},"lte":{"type":"number"}},"type":"object"},{"nullable":true}]},"OfficeAgentsRequest":{"additionalProperties":false,"properties":{"city":{"description":"Narrow agent matches to this city (exact, lowercase).","type":"string"},"companyName":{"description":"Office name to match against `ModelMatch.AgentOffices.OfficeName` (fuzzy). Required when `officeId` is omitted.","type":"string"},"officeId":{"description":"Office key (mm_office_key). When set, the office is fetched first to resolve its name / city / state.","type":"string"},"pagination":{"$ref":"#/components/schemas/Pagination"},"sort":{"items":{"properties":{"field":{"enum":["name","volume","units"],"type":"string"},"order":{"$ref":"#/components/schemas/SortOrder"}},"required":["field"],"type":"object"},"type":"array"},"state":{"description":"Narrow agent matches to this state (exact, lowercase).","type":"string"}},"type":"object"},"OfficeDetail":{"allOf":[{"$ref":"#/components/schemas/OfficeSummary"},{"properties":{"email":{"nullable":true,"type":"string"},"fullAddress":{"nullable":true,"type":"string"},"number":{"nullable":true,"type":"string"},"phone":{"nullable":true,"type":"string"},"totalListPriceActive":{"description":"Total list price of active listings at this office","nullable":true,"type":"number"}},"type":"object"}]},"OfficeDetailResponse":{"properties":{"data":{"$ref":"#/components/schemas/OfficeDetail"}},"required":["data"],"type":"object"},"OfficeField":{"enum":["company","city","state","zip","agentCount","activeListings","volume","units","buyerVolume","buyerUnits","sellerVolume","sellerUnits","dualVolume","dualUnits","avgSalePrice","avgListPrice","teamSize"],"type":"string"},"OfficeFlatFilters":{"additionalProperties":false,"properties":{"activeListings":{"$ref":"#/components/schemas/NumericFilterValue"},"agentCount":{"$ref":"#/components/schemas/NumericFilterValue"},"avgListPrice":{"$ref":"#/components/schemas/NumericFilterValue"},"avgSalePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"buyerUnits":{"$ref":"#/components/schemas/NumericFilterValue"},"buyerVolume":{"$ref":"#/components/schemas/NumericFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"company":{"$ref":"#/components/schemas/TextFilterValue"},"dualUnits":{"$ref":"#/components/schemas/NumericFilterValue"},"dualVolume":{"$ref":"#/components/schemas/NumericFilterValue"},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"mode":{"enum":["and","or"],"type":"string"},"sellerUnits":{"$ref":"#/components/schemas/NumericFilterValue"},"sellerVolume":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"teamSize":{"$ref":"#/components/schemas/NumericFilterValue"},"units":{"$ref":"#/components/schemas/NumericFilterValue"},"volume":{"$ref":"#/components/schemas/NumericFilterValue"},"zip":{"$ref":"#/components/schemas/TextFilterValue"},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"OfficeListRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/OfficeFlatFilters"},"lenderFilters":{"items":{"$ref":"#/components/schemas/LenderFilterEntry"},"type":"array"},"lenderMatchMode":{"$ref":"#/components/schemas/LenderMatchMode"},"pagination":{"$ref":"#/components/schemas/Pagination"},"period":{"$ref":"#/components/schemas/Period"},"sort":{"items":{"properties":{"field":{"$ref":"#/components/schemas/OfficeField"},"order":{"$ref":"#/components/schemas/SortOrder"}},"required":["field"],"type":"object"},"type":"array"}},"type":"object"},"OfficeListResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/OfficeSummary"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"OfficeSummary":{"properties":{"activeListings":{"nullable":true,"type":"number"},"agentCount":{"description":"Number of agents at this office","nullable":true,"type":"number"},"avgListPrice":{"nullable":true,"type":"number"},"avgSalePrice":{"nullable":true,"type":"number"},"buyerUnits":{"nullable":true,"type":"number"},"buyerVolume":{"nullable":true,"type":"number"},"city":{"description":"City (stored lowercase on the source index)","nullable":true,"type":"string"},"company":{"nullable":true,"type":"string"},"coordinates":{"nullable":true,"properties":{"lat":{"type":"number"},"lon":{"type":"number"}},"required":["lat","lon"],"type":"object"},"country":{"nullable":true,"type":"string"},"dualUnits":{"nullable":true,"type":"number"},"dualVolume":{"nullable":true,"type":"number"},"id":{"description":"Office key (mm_office_key)","type":"string"},"lastCountedAt":{"nullable":true,"type":"string"},"locationType":{"nullable":true,"type":"string"},"sellerUnits":{"nullable":true,"type":"number"},"sellerVolume":{"nullable":true,"type":"number"},"state":{"description":"State abbreviation (stored lowercase on the source index)","nullable":true,"type":"string"},"street":{"nullable":true,"type":"string"},"teamSize":{"nullable":true,"type":"number"},"units":{"nullable":true,"type":"number"},"volume":{"nullable":true,"type":"number"},"zip":{"nullable":true,"type":"string"}},"required":["id"],"type":"object"},"OrFilter":{"properties":{"children":{"description":"Array of filter expressions (OR)","items":{"$ref":"#/components/schemas/FilterNode"},"type":"array"},"type":{"enum":["or"],"type":"string"}},"required":["type","children"],"type":"object"},"OriginatorChartRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"borrowerStatus":{"$ref":"#/components/schemas/LoanBorrowerStatusFilterValue"},"broker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Broker shop NMLS id (digits only). A broker is a company — resolve a broker name to its NMLS id via instantSearch (or listCompanies)."}]},"buyerEntityType":{"$ref":"#/components/schemas/BooleanFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"conforming":{"$ref":"#/components/schemas/BooleanFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County name (e.g. \"Broward\") or 5-digit FIPS code. Names resolve to FIPS server-side; include a `state` filter to disambiguate."}]},"currentBalance":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated remaining principal balance (~19% populated). Approximate current equity as `homeValue` (AVM) minus this."}]},"employer":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Employer/company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Point-in-time equity recorded on the loan (sparse, ~10%). NOT a live current-equity figure. For HELOC/cash-out targeting on up-to-date equity, use properties search (listProperties) instead — its equity is far better populated and current."}]},"excludeBroker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans brokered by this broker-shop NMLS id (digits only) — the inverse of `broker`."}]},"excludeCity":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this city — the inverse of `city`."}]},"excludeLender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans from this lender ID (\"everyone but X\") — the inverse of `lender`, same id contract (resolve via instantSearch/listLenders). Loans with no lender stay in the results."}]},"excludeLoanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans funded by this company NMLS id (digits only) — the inverse of `loanCompany`."}]},"excludeOriginator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans with this originator NMLS id (digits only) — the inverse of `originator`. Common for 'everyone but my own shop' lists."}]},"excludeState":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this state (2-letter code, e.g. \"CA\") — the inverse of `state`. For \"everywhere but this state\" lists."}]},"excludeZipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this ZIP code — the inverse of `zipCode`."}]},"fips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exact 5-digit county FIPS code (no name resolution) — the code-only escape hatch alongside `county`."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"homeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"AVM (automated valuation) at the linked property (~26%, MLS-linked). Pair with `currentBalance` to approximate current equity."}]},"includeUnknownOriginator":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Include loans that have no originator NMLS id. Omitted/false (default): such loans are excluded — the vast majority are pre-2016 public records with no linkable originator. true: include them. Note that the default scopes results to loans with a known originator (~2016+ recordings)."}]},"interestRate":{"$ref":"#/components/schemas/NumericFilterValue"},"lender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender ID — the normalized lender-dictionary key, NOT a fuzzy name match. Resolve a lender via instantSearch (or listLenders) and pass the `id` it returns (e.g. \"mortgage_rocket\" or \"mortgage rocket\"). Underscores and letter case are normalized, so either id surface works. A stored normalized lender name (what the `slice: \"lender\"` chart buckets emit) is also accepted, so a chart bucket key filters directly. A value that is neither returns 400 rather than silently matching nothing — to search by lender NAME, use `lenderName`."}]},"lenderName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender name as recorded on the loan document — fuzzy, all-terms match (e.g. \"Fifth Third\"). The name counterpart to the exact-id `lender` filter; use `lender` when you have a resolved id, and this when you only have a name."}]},"loanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Funding/loan company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"loanType":{"$ref":"#/components/schemas/LoanTypeFilterValue"},"ltvAtOrigination":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan-to-value at ORIGINATION (sparse). This is not a current LTV — there is no stored current-LTV field on loans."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"mortgageDate":{"$ref":"#/components/schemas/DateFilterValue"},"originator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Loan originator NMLS id (digits only). To search by name use `originatorName`, or resolve a name to its id via instantSearch."}]},"originatorName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (same originator can return wildly different counts by name string). Resolve the loan officer via instantSearch and filter by `originator` (exact NMLS id) instead. Still functional for now."}]},"saleDate":{"$ref":"#/components/schemas/DateFilterValue"},"salePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"transactionType":{"$ref":"#/components/schemas/LoanTransactionTypeFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zipCode` — same ZIP filter, accepted for cross-entity key parity."}]},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"measure":{"$ref":"#/components/schemas/ChartMeasure"},"nmlsId":{"type":"string"},"nmlsIds":{"items":{"type":"string"},"type":"array"},"period":{"$ref":"#/components/schemas/Period"},"slice":{"$ref":"#/components/schemas/OriginatorSlice"}},"required":["slice"],"type":"object"},"OriginatorCompanyCategoryFilterValue":{"anyOf":[{"description":"One of (case-insensitive): BANK, CU, OTHER","enum":["BANK","CU","OTHER"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): BANK, CU, OTHER","enum":["BANK","CU","OTHER"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"OriginatorContact":{"nullable":true,"properties":{"cellPhone":{"nullable":true,"type":"string"},"employerAddress":{"nullable":true,"type":"string"},"employerCity":{"nullable":true,"type":"string"},"employerCompany":{"nullable":true,"type":"string"},"employerCompanyId":{"nullable":true,"type":"string"},"employerState":{"nullable":true,"type":"string"},"employerType":{"nullable":true,"type":"string"},"employerWebsite":{"nullable":true,"type":"string"},"employerZip":{"nullable":true,"type":"string"},"facebook":{"nullable":true,"type":"string"},"linkedin":{"nullable":true,"type":"string"},"officePhone":{"nullable":true,"type":"string"},"officePhoneExt":{"nullable":true,"type":"string"},"personalEmail":{"nullable":true,"type":"string"},"twitter":{"nullable":true,"type":"string"},"website":{"nullable":true,"type":"string"},"workEmail":{"nullable":true,"type":"string"}},"type":"object"},"OriginatorDetail":{"allOf":[{"$ref":"#/components/schemas/OriginatorSummary"},{"properties":{"careerHistory":{"nullable":true,"properties":{"employerCount":{"description":"Number of employers on the origination record. May be lower than `employers.length`, which also counts companies known only from the NMLS sponsorship record.","nullable":true,"type":"number"},"employers":{"description":"Employer history, current employer(s) first, then most recent activity.","items":{"properties":{"avgLoanAmount":{"nullable":true,"type":"number"},"cityCount":{"nullable":true,"type":"number"},"countyCount":{"nullable":true,"type":"number"},"isCurrent":{"description":"True when the originator is still with this employer. Taken from the NMLS sponsorship record when there is one (it is maintained independently of loan closings, so an originator who has not closed recently still reads as current), otherwise from an open production window.","type":"boolean"},"name":{"nullable":true,"type":"string"},"nmlsId":{"description":"The employer's NMLS company ID.","nullable":true,"type":"string"},"producedFrom":{"description":"First loan origination seen under this employer. Null when the originator never closed a loan here.","nullable":true,"type":"string"},"producedTo":{"description":"Most recent loan origination seen under this employer. Null means production was still open at the last scoring run — it does NOT mean no production.","nullable":true,"type":"string"},"registeredFrom":{"description":"Start of the NMLS company sponsorship. Null when this employer appears only in the origination record.","nullable":true,"type":"string"},"registeredTo":{"description":"End of the NMLS company sponsorship. Null when the sponsorship is still open.","nullable":true,"type":"string"},"sources":{"description":"Which record this employer came from. `production` only = they closed loans here but the sponsorship record does not carry the company; `registration` only = sponsored here with no closed loans on file.","items":{"enum":["production","registration"],"type":"string"},"type":"array"},"stateCount":{"description":"Distinct states originated in under this employer.","nullable":true,"type":"number"},"topStates":{"description":"The employer's three largest states by volume. The full footprint is available from the originator breakdown endpoints.","items":{"properties":{"percentOfVolume":{"description":"Share of this employer's volume originated in this state, 0–100.","nullable":true,"type":"number"},"state":{"description":"Two-letter state code.","nullable":true,"type":"string"},"stateName":{"nullable":true,"type":"string"},"units":{"nullable":true,"type":"number"},"volume":{"nullable":true,"type":"number"}},"type":"object"},"type":"array"},"units":{"nullable":true,"type":"number"},"volume":{"description":"All-time origination volume under this employer (not period-scoped). Zero is a real answer — a registered stint with no closed loans.","nullable":true,"type":"number"},"zipCount":{"nullable":true,"type":"number"}},"required":["isCurrent","topStates","sources"],"type":"object"},"type":"array"}},"required":["employers"],"type":"object"},"communityLending":{"$ref":"#/components/schemas/EntityCommunityLending"},"contact":{"$ref":"#/components/schemas/OriginatorContact"},"licenses":{"nullable":true},"locations":{"nullable":true},"registration":{"$ref":"#/components/schemas/OriginatorRegistration"},"registrations":{"nullable":true},"scored":{"nullable":true},"sponsorships":{"nullable":true},"title":{"nullable":true,"type":"string"}},"type":"object"}]},"OriginatorDetailResponse":{"properties":{"data":{"$ref":"#/components/schemas/OriginatorDetail"}},"required":["data"],"type":"object"},"OriginatorFootprintFilter":{"additionalProperties":false,"properties":{"avgLoanAmount":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"Mean loan size INSIDE this market."}]},"city":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"description":"Production city — a name (`Orlando`, best paired with `state`) or a location id from `instantSearch` / `suggestLocations`. An unrecognized name is a 400, never a silent zero."},"county":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"description":"Production county — a 5-digit FIPS code (`06037`) or a county name (`Riverside`, best paired with `state`)."},"dimension":{"description":"Which footprint to address. Normally inferred from the location key you pass; name it explicitly to ask the ANY-market question (`{dimension:'city', volume:{gte:15000000}}` = 'some single city where they did $15M').","enum":["zip","city","county","state","lender"],"type":"string"},"lender":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"description":"Funding lender, as an id from `listLenders` or `instantSearch`. Lender names are stored in a normalized dictionary form, so a typed name does not match — resolve it first."},"not":{"description":"Invert the whole entry: match producers with NO market matching it (e.g. 'does not send loans to this lender').","type":"boolean"},"product":{"allOf":[{"$ref":"#/components/schemas/FootprintProductFilter"},{"description":"Correlate a product INSIDE this market — '$1M of FHA in Orlando'."}]},"shareOfVolume":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"This market's share of the originator's total volume for the period, as a 0–100 PERCENT (not a 0–1 fraction). `{gte:50}` = 'this market is at least half their book'."}]},"state":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"description":"Two-letter state code or full state name. Alongside `city` or `county` it DISAMBIGUATES that place rather than adding a second predicate; on its own it selects the state footprint."},"units":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"Loan count INSIDE this market during the selected period."}]},"volume":{"allOf":[{"$ref":"#/components/schemas/FootprintRange"},{"description":"Dollar volume originated INSIDE this market during the selected period."}]},"zip":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"description":"Production 5-digit zip code."}},"type":"object"},"OriginatorListRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"affordableHousingTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in qualified affordable-housing tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"affordableHousingTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in qualified census tracts for affordable-housing programs, 0-100 (`{gte:25}` = 27,209 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgAsianPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean Asian (non-Hispanic) share of the population in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgBlackPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean Black (non-Hispanic) share of the population in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgDenialRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean share of mortgage applications denied in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgFamilyIncome":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean median family income of the tracts the entity lent in, in whole dollars. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgHispanicPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean Hispanic or Latino share of the population in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgHomeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean median home value across the tracts the entity lent in, in whole dollars. A neighborhood statistic — not the entity's average loan size, which is `avgLoanAmount`. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgHomeownershipRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean owner-occupied share of housing units in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgHouseholdIncome":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean median household income of the tracts the entity lent in, in whole dollars (e.g. `{lte:60000}`). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgIncomeVsMetroPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean tract income relative to its metro area, where `100` is parity — `{lt:80}` is the CRA low/moderate band, and values legitimately exceed 100 (observed up to 412). NOT a 0-100 share. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgLoanAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"avgLowModHouseholdPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean HUD block-group low/moderate-income HOUSEHOLD share across the tracts the entity lent in, 0-100. A finer-grained measure than `lowModIncomeTractPct`, which counts whole tracts — not a duplicate of it. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMedianAge":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean median age of the population in the tracts the entity lent in, in years. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMilesToCollege":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean straight-line distance to the nearest college, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMilesToSchool":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean straight-line distance from the properties the entity lent on to the nearest school, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMilesToWorship":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean straight-line distance to the nearest place of worship, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgMinorityPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean non-white share of the population in the tracts the entity lent in, 0-100 (`{gte:50}` = 63,370 originators). `majorityMinorityTractPct` is the per-tract-threshold form of the same question. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgPopulation":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean population of the tracts the entity lent in. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgPovertyRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean share of the population below the poverty line in the tracts the entity lent in, 0-100. Pass whole percents — `{gte:0.2}` means 0.2%. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgTractApplications":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean number of mortgage applications reported in the tracts the entity lent in, over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgTractLoanVolume":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean mortgage dollar volume reported in the tracts the entity lent in, over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgTractOriginations":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean number of mortgage originations reported in the tracts the entity lent in, over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"avgWhiteNonHispanicPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean White (non-Hispanic) share of the population in the tracts the entity lent in, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"city":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Production city — matches originators who originated loans in this city during the selected period (NOT office/employer location). An LO can match this city while their row's displayed `city`/`state` is a different, higher-volume market."}]},"companyCategory":{"$ref":"#/components/schemas/OriginatorCompanyCategoryFilterValue"},"companyName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (one name can match many different people; partial names can silently return 0). Resolve the company via instantSearch and filter by `companyNmlsId` (exact NMLS id) instead. Still functional for now."}]},"companyNmlsId":{"$ref":"#/components/schemas/TextFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `countyFips`, identical behavior — production county by 5-digit FIPS code (e.g. `06037` = Los Angeles, CA) or by county name (`Riverside`, optionally with a sibling `state`). Pass an array to match any of several counties."}]},"countyCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"How many distinct counties the originator produced in during the selected period."}]},"countyFips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Production county. Accepts a 5-digit FIPS code (e.g. `04013` = Maricopa, AZ; `06037` = Los Angeles, CA) or a county name (`Riverside`, optionally with a sibling `state`) — names are resolved to a FIPS by the location dictionary. Matches originators who originated loans in this county during the selected period (NOT office/employer location). An ambiguous name returns candidates; an unrecognized one is a 400 naming `instantSearch`. Pass an array to match any of several counties."}]},"difficultDevelopmentAreaCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in HUD-designated difficult development areas. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"difficultDevelopmentAreaPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in HUD-designated difficult development areas, 0-100 (`{gte:25}` = 93,397 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"distressedTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in distressed-or-underserved tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"distressedTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in distressed-or-underserved nonmetropolitan middle-income tracts, 0-100 (`{gte:25}` = 11,773 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"firstName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (one name can match many different people; partial names can silently return 0). Note: firstName maps to the FULL analyzed `name` field, not a dedicated first-name leaf, so it also matches middle names. Resolve the originator via instantSearch and filter by `nmlsId` (exact NMLS id) instead. Still functional for now."}]},"floodHazardTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in a FEMA special flood hazard area. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"floodHazardTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in a FEMA special flood hazard area, 0-100 (`{gte:25}` = 5,212 originators). `predominantFloodZone` gives the specific zone code. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"hasEmail":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Whether the originator's profile carries at least one email address (101,566 do). Same `true`-is-a-guarantee / `false`-means-'none on the profile' caveat as `hasPhone`."}]},"hasPhone":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Whether the originator's profile carries at least one phone number (250,077 do). `true` is a guarantee — those records have a number. `false` means 'none on the profile', not 'no number exists': the detail response also draws on a broader contact source, so a small share of `false` records still show a phone when fetched individually."}]},"hasSocial":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Whether the originator's profile carries a social profile link — LinkedIn, Facebook or X/Twitter. Deliberately excludes a plain company website, which is tracked separately and is not a social presence."}]},"isBranchManager":{"$ref":"#/components/schemas/BooleanFilterValue"},"isBroker":{"$ref":"#/components/schemas/BooleanFilterValue"},"isWorking":{"$ref":"#/components/schemas/BooleanFilterValue"},"lastName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (one name can match many different people; partial names can silently return 0). Note: lastName maps to the FULL analyzed `name` field, not a dedicated last-name leaf, so it also matches middle names. Resolve the originator via instantSearch and filter by `nmlsId` (exact NMLS id) instead. Still functional for now."}]},"lenderCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"How many distinct lenders the originator sent loans to during the selected period. `{lte:1}` finds single-outlet producers."}]},"licenseCount":{"$ref":"#/components/schemas/NumericFilterValue"},"loanType":{"$ref":"#/components/schemas/OriginatorLoanTypeFilterValue"},"loansWithCommunityData":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"How many of the entity's loans in the selected period resolved to a neighborhood — the DENOMINATOR every Community Lending share is taken over. Pair it with a share filter (`{gte:25}`, 60,399 originators) so a 100% share off two loans does not read as a 100% share off two hundred. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"lowModIncomeTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans that landed in a low- or moderate-income tract, as a count rather than a share. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"lowModIncomeTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans that landed in a low- or moderate-income tract under the Community Reinvestment Act, 0-100. `{gte:50}` = 'at least half their book is LMI' (36,977 originators, 655 companies, 648 branches). Pass whole percents — `{gte:0.5}` means half of one percent and matches nearly everyone. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"majorityMinorityTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in majority-minority tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"majorityMinorityTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in majority-minority tracts, 0-100 (`{gte:50}` = 65,654 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"marketConcentration":{"$ref":"#/components/schemas/MarketConcentrationFilterValue"},"marketCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"How many distinct CITIES the originator produced in during the selected period. `{gte:10}` = a broad, multi-market book; `{lte:2}` = concentrated. Counts markets, not loans."}]},"mode":{"enum":["and","or"],"type":"string"},"name":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (one name can match many different people; partial names can silently return 0). Resolve the originator via instantSearch and filter by `nmlsId` (exact NMLS id) instead. Still functional for now."}]},"nmlsId":{"$ref":"#/components/schemas/TextFilterValue"},"opportunityZoneCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in Opportunity Zone tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"opportunityZonePct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in federally designated Opportunity Zone tracts, 0-100 (`{gte:10}` = 33,520 originators — this is a small-share filter, a 50% floor finds almost nobody). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"peakMonthUnits":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"The originator's BEST single month of loan COUNT inside the selected period. `{gte:20}` = 'they closed 20+ loans in some month' (7,295 originators over the last 12 months). Same peak semantics as `peakMonthVolume`."}]},"peakMonthVolume":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"The originator's BEST single month of volume inside the selected period. `{gte:10000000}` = 'they had at least one $10M month' (4,803 originators over the last 12 months); `{lte:X}` means no month exceeded X, so it is a true ceiling on their best month. There is no way to ask about a SPECIFIC month here — the per-month buckets are not individually addressable — so use `POST /originators/{nmlsId}/analytics/time-series` for a month-by-month series."}]},"predominantFloodZone":{"$ref":"#/components/schemas/EntityPredominantFloodZoneFilterValue"},"predominantIncomeLevel":{"$ref":"#/components/schemas/EntityPredominantIncomeLevelFilterValue"},"producersOnly":{"$ref":"#/components/schemas/BooleanFilterValue"},"regulators":{"$ref":"#/components/schemas/TextFilterValue"},"ruralGradient":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean remoteness of the tracts the entity lent in, on an ORDINAL 1-10 scale (1 = metropolitan core, 10 = most remote). This is a code, not a percent — `{gte:7}` selects the deepest-rural books (8,886 originators). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"ruralTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in rural tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"ruralTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in rural tracts, 0-100 (`{gte:50}` = 24,006 originators). `ruralGradient` is the finer, ordinal form. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"sponsoredAvgLoanAmount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean loan size on the originator's sponsored-employer production."}]},"sponsoredShare":{"anyOf":[{"type":"number"},{"description":"Match any value","items":{"type":"number"},"type":"array"},{"description":"Numeric range. Excludes null/missing-field docs by default; add `includeNulls: true` to keep them.","properties":{"gt":{"type":"number"},"gte":{"type":"number"},"includeNulls":{"description":"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.","type":"boolean"},"lt":{"type":"number"},"lte":{"type":"number"}},"type":"object"},{"nullable":true}],"description":"Share of the originator's period volume originated under their SPONSORING employer, as a 0–100 percent. The retail counterpart of `thirdPartyShare`; same denominator, same exclusion of zero-volume records, and the two do not sum to 100."},"sponsoredUnits":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan count the originator produced under their sponsoring employer during the selected period."}]},"sponsoredVolume":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Dollar volume the originator produced under their sponsoring employer during the selected period."}]},"state":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Production state — matches originators who originated loans in this state during the selected period (NOT office/employer location). Multi-state LOs match any state they produced in; each row's `state` shows only their primary (highest-volume) market."}]},"stateCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"How many distinct states the originator produced in during the selected period. `{gte:2}` finds multi-state producers."}]},"thirdPartyAvgLoanAmount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mean loan size on the originator's third-party (broker) production."}]},"thirdPartyShare":{"anyOf":[{"type":"number"},{"description":"Match any value","items":{"type":"number"},"type":"array"},{"description":"Numeric range. Excludes null/missing-field docs by default; add `includeNulls: true` to keep them.","properties":{"gt":{"type":"number"},"gte":{"type":"number"},"includeNulls":{"description":"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.","type":"boolean"},"lt":{"type":"number"},"lte":{"type":"number"}},"type":"object"},{"nullable":true}],"description":"Share of the originator's period volume submitted through a THIRD-PARTY (broker) relationship, as a 0–100 percent. `{gte:50}` = 'most of their book is wholesale' (52,507 originators over the last 12 months). Computed against their total period volume; an originator with no volume in the period has no share and is excluded rather than counted as zero. This and `sponsoredShare` do not sum to 100 — the remainder is retail."},"thirdPartyUnits":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan count the originator submitted through third-party (broker) relationships during the selected period."}]},"thirdPartyVolume":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Dollar volume the originator submitted through third-party (broker) relationships during the selected period."}]},"totalLicenses":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"How many licenses appear on the originator's record in total, including expired and superseded ones. Distinct from `licenseCount`, which is the CURRENT registration snapshot and runs lower (it is also only on file for about 60% of originators, where this is on all of them). Use `totalLicenses` for career breadth, `licenseCount` for who is licensed right now."}]},"totalLoans":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Lifetime originated loan count across every period on record. Not scoped by `period` — use `units` for the selected period."}]},"transactionType":{"$ref":"#/components/schemas/OriginatorTransactionTypeFilterValue"},"units":{"$ref":"#/components/schemas/NumericFilterValue"},"usdaEligibleTractCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Number of the entity's loans in USDA-eligible tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"usdaEligibleTractPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the entity's tract-resolved loans in tracts eligible for USDA rural housing programs, 0-100 (`{gte:50}` = 90,392 originators). Broader than `ruralTractPct` — eligibility reaches well past what is classified rural. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"volume":{"$ref":"#/components/schemas/NumericFilterValue"},"yearsInIndustry":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Years of recorded industry tenure. Lifetime, NOT scoped by `period`. `{gte:10}` finds established originators (246,091 today); `{lte:2}` finds new entrants."}]},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Production zip code — matches originators who originated loans in this 5-digit zip during the selected period (NOT office/employer location). Pass an array to match any of several zips."}]},"zipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zip` — production zip code (5-digit). Identical behavior; kept for callers using the loans/sales spelling."}]},"zipCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"How many distinct 5-digit zip codes the originator produced in during the selected period."}]}},"type":"object"},"footprint":{"anyOf":[{"$ref":"#/components/schemas/OriginatorFootprintFilter"},{"items":{"$ref":"#/components/schemas/OriginatorFootprintFilter"},"type":"array"}],"description":"Scoped market filter(s). Each entry names ONE market (city / county / state / zip / lender) and the metric bounds that must hold INSIDE it — `{city:'Orlando', state:'FL', volume:{gte:15000000}}` means '$15M of production in Orlando', not '$15M somewhere and a loan in Orlando'. Several entries AND together."},"lenderFilters":{"items":{"$ref":"#/components/schemas/LenderFilterEntry"},"type":"array"},"lenderMatchMode":{"$ref":"#/components/schemas/LenderMatchMode"},"pagination":{"$ref":"#/components/schemas/Pagination"},"period":{"$ref":"#/components/schemas/Period"},"sort":{"items":{"properties":{"field":{"enum":["nmlsId","name","firstName","lastName","volume","units","scopedVolume","scopedUnits","state","city","countyFips","producersOnly"],"type":"string"},"order":{"$ref":"#/components/schemas/SortOrder"}},"required":["field"],"type":"object"},"type":"array"}},"type":"object"},"OriginatorListResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/OriginatorSummary"},"type":"array"},"locationNormalizations":{"description":"How each location filter value resolved. Present when a `city`/`county`/`state`/`zip` filter was supplied.","items":{"$ref":"#/components/schemas/LocationNormalization"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"OriginatorLoanTypeFilterValue":{"anyOf":[{"description":"One of (case-insensitive): conventional, fha, va, he, heloc, building, commercial, stand_alone_refi, closed_end, reverse, usda, stand_alone_second, aggregate, seller_take_back, sba_participation_trust_deed, balloon, opened_end, assumption, negative_amortization, land_contract, trade, modification, unknown","enum":["conventional","fha","va","he","heloc","building","commercial","stand_alone_refi","closed_end","reverse","usda","stand_alone_second","aggregate","seller_take_back","sba_participation_trust_deed","balloon","opened_end","assumption","negative_amortization","land_contract","trade","modification","unknown"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): conventional, fha, va, he, heloc, building, commercial, stand_alone_refi, closed_end, reverse, usda, stand_alone_second, aggregate, seller_take_back, sba_participation_trust_deed, balloon, opened_end, assumption, negative_amortization, land_contract, trade, modification, unknown","enum":["conventional","fha","va","he","heloc","building","commercial","stand_alone_refi","closed_end","reverse","usda","stand_alone_second","aggregate","seller_take_back","sba_participation_trust_deed","balloon","opened_end","assumption","negative_amortization","land_contract","trade","modification","unknown"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"OriginatorMarketBucket":{"properties":{"avgLoanAmount":{"description":"Mean loan size in this market.","nullable":true,"type":"number"},"key":{"description":"The market's key as the source stores it. Form varies with `source` (a rollup city is `city|state`, a live city is the city name) — use `name` for display and grouping.","nullable":true,"type":"string"},"name":{"description":"Display label for the market, in the same form the matching `/breakdowns` route publishes: a county reads `Middlesex County (MA)`, a state `MA`, a city `Belmont` (with a `, MA` qualifier when the market is a city within one state). Identical for a given market whichever `source` served the request, so labels can be compared across surfaces; `key` is the source-native identity and is not.","nullable":true,"type":"string"},"shareOfBook":{"description":"Share of the LO's whole period volume, 0–100. Null on live transaction data, which carries no stored share.","nullable":true,"type":"number"},"shareOfScope":{"description":"Share of the volume of the markets RETURNED, 0–100. Sums to 100 across the grain — this is the one a chart should render.","nullable":true,"type":"number"},"units":{"description":"Loans in this market.","nullable":true,"type":"number"},"volume":{"description":"Dollar volume originated in this market.","nullable":true,"type":"number"}},"required":["key","name","volume","units","avgLoanAmount","shareOfScope","shareOfBook"],"type":"object"},"OriginatorMarketsCommunityLending":{"description":"The Community Lending mix of this footprint: the neighborhood characteristics of where the production landed, as percentages on a 0-100 scale. Null when nothing in scope resolved to a neighborhood — an absent block, never a row of zeroes, because 'no data' and '0%' are different answers. Read `basis` before comparing two responses. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"properties":{"affordableHousingTractPct":{"description":"Share of production, 0-100, in neighborhoods carrying an affordable-housing designation. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"basis":{"description":"Which measurement produced this block, and they are NOT the same number. `entityRollup` is the neighborhood mix of the entity's own production over the whole period — the default. `marketsInScope` is the neighborhood profile of the markets the request selected, weighted by the entity's production in each, and is what any ZIP, date or filter scope returns, because a whole-period rollup cannot be re-cut to a narrower question.","enum":["entityRollup","marketsInScope"],"type":"string"},"coveredProductionPct":{"description":"`marketsInScope` only — what share of the weighted production, 0-100, sits in a market that resolved to neighborhood data. Below 100 means the mix describes part of the footprint, not all of it.","nullable":true,"type":"number"},"difficultDevelopmentAreaPct":{"description":"Share of production, 0-100, in designated difficult development areas. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"distressedTractPct":{"description":"Share of production, 0-100, in distressed or underserved nonmetropolitan middle-income neighborhoods. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"floodHazardTractPct":{"description":"Share of production, 0-100, in neighborhoods inside a special flood hazard area. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"incomeLevelMix":{"description":"`marketsInScope` only — the full relative-income distribution of the neighborhoods, 0-100, summing to about 100. Null on `entityRollup`, which stores the predominant band but no distribution; publishing one derived from a single label would be a histogram nobody measured. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"properties":{"low":{"nullable":true,"type":"number"},"middle":{"nullable":true,"type":"number"},"moderate":{"nullable":true,"type":"number"},"upper":{"nullable":true,"type":"number"}},"required":["low","moderate","middle","upper"],"type":"object"},"loansWithCommunityData":{"description":"`entityRollup` only — how many of the entity's transactions in the period resolved to a neighborhood. This is the denominator every share below is a share OF, so read it first: a 100% share over three transactions is not a footprint.","nullable":true,"type":"number"},"lowModIncomeTractPct":{"description":"Share of production, 0-100, in low- or moderate-income neighborhoods. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"majorityMinorityTractPct":{"description":"Share of production, 0-100, in majority-minority neighborhoods. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"marketsInScope":{"description":"`marketsInScope` only — ZIP markets the mix considered, including any that carried no neighborhood data.","nullable":true,"type":"number"},"marketsWithCommunityData":{"description":"`marketsInScope` only — ZIP markets that resolved to neighborhood data.","nullable":true,"type":"number"},"opportunityZonePct":{"description":"Share of production, 0-100, in designated Opportunity Zones. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"predominantIncomeLevel":{"description":"The most common relative-income classification of the neighborhoods, on the standard four-band scale. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","enum":["low","moderate","middle","upper",null],"nullable":true,"type":"string"},"ruralTractPct":{"description":"Share of production, 0-100, in neighborhoods classified rural. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"usdaEligibleTractPct":{"description":"Share of production, 0-100, in neighborhoods eligible for USDA rural housing programs. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"}},"required":["basis","loansWithCommunityData","marketsWithCommunityData","marketsInScope","coveredProductionPct","predominantIncomeLevel","incomeLevelMix","lowModIncomeTractPct","majorityMinorityTractPct","ruralTractPct","opportunityZonePct","affordableHousingTractPct","distressedTractPct","usdaEligibleTractPct","floodHazardTractPct","difficultDevelopmentAreaPct"],"type":"object"},"OriginatorMarketsRequest":{"additionalProperties":false,"properties":{"dateRange":{"description":"Custom window. A period is a fixed pre-aggregated window and cannot be re-cut, so any bound here switches the response to live transaction data.","properties":{"from":{"pattern":"^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$/u","type":"string"},"to":{"pattern":"^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$/u","type":"string"}},"type":"object"},"limit":{"description":"Markets returned per grain (default 100). The summary is computed over the whole footprint FIRST and is not affected by this.","maximum":500,"minimum":1,"type":"integer"},"period":{"allOf":[{"$ref":"#/components/schemas/Period"},{"description":"Production period the markets are read from (default last12Months)."}]},"zipCodes":{"description":"Narrow the footprint to these ZIP codes. 5-digit; ZIP+4 and zero-stripped forms are accepted and normalized. A value that is not 1–5 digits returns 400 naming it rather than being ignored. Any value here switches the response to live transaction data.","example":["92683","92703"],"items":{"type":"string"},"maxItems":200,"type":"array"}},"type":"object"},"OriginatorMarketsResponse":{"properties":{"nmlsId":{"type":"string"},"notes":{"description":"Plain-language caveats that apply to this response.","items":{"type":"string"},"type":"array"},"period":{"type":"string"},"rollups":{"$ref":"#/components/schemas/OriginatorMarketsRollups"},"scope":{"description":"The scope as applied, after normalization — echo it back to see what the request actually asked.","properties":{"dateRange":{"nullable":true,"properties":{"from":{"nullable":true,"type":"string"},"to":{"nullable":true,"type":"string"}},"required":["from","to"],"type":"object"},"zipCodes":{"items":{"type":"string"},"nullable":true,"type":"array"}},"required":["zipCodes","dateRange"],"type":"object"},"source":{"description":"Where the markets were read from. `documentRollup` is the LO's pre-aggregated footprint; `liveTransactions` aggregates the LO's loans directly, which is what any scope requires.","enum":["documentRollup","liveTransactions"],"type":"string"},"sourceReasons":{"description":"Why that source was chosen.","items":{"enum":["doc-rollup","coverage-empty","zip-scope","date-scope","live-only-metric"],"type":"string"},"type":"array"},"summary":{"$ref":"#/components/schemas/OriginatorMarketsSummary"},"totals":{"$ref":"#/components/schemas/OriginatorMarketsTotals"},"zips":{"description":"The ZIP-level footprint, largest volume first.","items":{"$ref":"#/components/schemas/OriginatorMarketBucket"},"type":"array"}},"required":["nmlsId","period","source","sourceReasons","scope","summary","zips","rollups","totals","notes"],"type":"object"},"OriginatorMarketsRollups":{"description":"Coarser views of the same scope. Each grain is its own pre-aggregation, not a re-cut of the ZIPs, so grains need not sum to each other.","properties":{"cities":{"items":{"$ref":"#/components/schemas/OriginatorMarketBucket"},"type":"array"},"counties":{"items":{"$ref":"#/components/schemas/OriginatorMarketBucket"},"type":"array"},"states":{"items":{"$ref":"#/components/schemas/OriginatorMarketBucket"},"type":"array"}},"required":["cities","counties","states"],"type":"object"},"OriginatorMarketsSummary":{"properties":{"avgLoanAmount":{"description":"Volume-weighted mean loan size — Σ volume ÷ Σ units, never an unweighted mean of the per-market averages.","nullable":true,"type":"number"},"communityLending":{"$ref":"#/components/schemas/OriginatorMarketsCommunityLending"},"markets":{"description":"Placed markets the summary covers.","type":"number"},"shareOfBook":{"description":"How much of the LO's whole period book the ZIP markets are, 0–100. Read it as COVERAGE, and expect it below 100 even with no filter: part of the gap is production that could not be placed at all (reported in `unresolved`) and part is production carrying no ZIP. The coarser grains in `rollups` are separate pre-aggregations with their own — usually higher — coverage, so they can legitimately add up to more than this. Null on live transaction data.","nullable":true,"type":"number"},"truncatedMarkets":{"description":"True when the source returned only the largest markets, so the summary covers those and not the full tail.","type":"boolean"},"units":{"description":"Σ loans of those markets.","nullable":true,"type":"number"},"unresolved":{"$ref":"#/components/schemas/OriginatorMarketsUnresolved"},"volume":{"description":"Σ volume of the markets in scope — NOT the LO's period total, which is `totals.volume`.","nullable":true,"type":"number"}},"required":["markets","volume","units","avgLoanAmount","shareOfBook","truncatedMarkets","unresolved","communityLending"],"type":"object"},"OriginatorMarketsTotals":{"properties":{"avgLoanAmount":{"description":"The LO's mean loan size for the period.","nullable":true,"type":"number"},"footprintCoverage":{"description":"What share of `volume` the returned ZIP markets account for, 0–100. Null on live transaction data, where the window and the period block are not the same denominator.","nullable":true,"type":"number"},"units":{"description":"The LO's whole loan count for the period.","nullable":true,"type":"number"},"volume":{"description":"The LO's whole volume for the period.","nullable":true,"type":"number"}},"required":["volume","units","avgLoanAmount","footprintCoverage"],"type":"object"},"OriginatorMarketsUnresolved":{"description":"Production the source could not attribute to a place, held OUT of the summary and the market lists and reported on its own.","properties":{"markets":{"description":"Buckets the source could not attribute to a place.","type":"number"},"shareOfBook":{"nullable":true,"type":"number"},"units":{"nullable":true,"type":"number"},"volume":{"nullable":true,"type":"number"}},"required":["markets","volume","units","shareOfBook"],"type":"object"},"OriginatorRegistration":{"nullable":true,"properties":{"address":{"nullable":true},"city":{"nullable":true,"type":"string"},"companyCategory":{"nullable":true,"type":"string"},"companyName":{"nullable":true,"type":"string"},"companyNmlsId":{"nullable":true,"type":"string"},"hasDisciplinaryAction":{"nullable":true,"type":"boolean"},"isBranchManager":{"nullable":true,"type":"boolean"},"isWorking":{"nullable":true,"type":"boolean"},"licenseCount":{"nullable":true,"type":"number"},"licensedSinceDate":{"nullable":true,"type":"string"},"licensedStates":{"items":{"type":"string"},"nullable":true,"type":"array"},"licenses":{"nullable":true},"otherNames":{"nullable":true},"regulators":{"items":{"type":"string"},"nullable":true,"type":"array"},"sponsorships":{"nullable":true},"state":{"nullable":true,"type":"string"}},"type":"object"},"OriginatorSlice":{"enum":["transactionType","loanType","city","county","state","zip","lender"],"type":"string"},"OriginatorSummary":{"properties":{"avgLoanAmount":{"description":"Mean loan size for the selected period, derived from the TOTAL `volume` and `units` across ALL markets — NOT scoped to any geographic filter in this request. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank originators by it. `POST /originators/{nmlsId}/breakdowns/counties` (or `/cities`, `/states`, `/zip-codes`) breaks ONE originator's production out by market.","nullable":true,"type":"number"},"city":{"nullable":true,"type":"string"},"companyName":{"nullable":true,"type":"string"},"conventionalPct":{"nullable":true,"type":"number"},"email":{"nullable":true,"type":"string"},"employerCity":{"nullable":true,"type":"string"},"employerState":{"nullable":true,"type":"string"},"fhaPct":{"nullable":true,"type":"number"},"firstName":{"nullable":true,"type":"string"},"id":{"description":"Document ID","type":"string"},"lastName":{"nullable":true,"type":"string"},"name":{"nullable":true,"type":"string"},"nmlsId":{"nullable":true,"type":"string"},"phone":{"nullable":true,"type":"string"},"purchaseUnits":{"nullable":true,"type":"number"},"purchaseVolume":{"nullable":true,"type":"number"},"refinanceUnits":{"nullable":true,"type":"number"},"refinanceVolume":{"nullable":true,"type":"number"},"scopedUnits":{"description":"The originator's loan count INSIDE the geography this request names, on the same basis as `scopedVolume`. Sortable. When the request names no geography — or names one only inside an `or` group or a negation — the scope is everywhere, and this is identical to the unscoped figure beside it. Reconciles with `POST /originators/{nmlsId}/markets` for the same geography and period: both are read from the same per-market rollup on the same record.","nullable":true,"type":"number"},"scopedVolume":{"description":"The originator's dollar production INSIDE the geography this request names — what a `state`/`city`/`county`/`zip` filter was almost certainly asking for, and what the sibling `volume` is not. Sort by `scopedVolume` to rank originators by it. When the request names no geography — or names one only inside an `or` group or a negation — the scope is everywhere, and this is identical to the unscoped figure beside it. Reconciles with `POST /originators/{nmlsId}/markets` for the same geography and period: both are read from the same per-market rollup on the same record.","nullable":true,"type":"number"},"state":{"nullable":true,"type":"string"},"units":{"description":"The originator's TOTAL loan count for the selected period across ALL markets — NOT scoped to any geographic filter in this request, exactly as described on `volume`. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank originators by it. `POST /originators/{nmlsId}/breakdowns/counties` (or `/cities`, `/states`, `/zip-codes`) breaks ONE originator's production out by market.","nullable":true,"type":"number"},"vaPct":{"nullable":true,"type":"number"},"volume":{"description":"The originator's TOTAL dollar production for the selected period across ALL markets — NOT scoped to any geographic filter (`state`/`city`/`county`/`countyFips`/`zip`/`zipCode`) in this request. Those filters select WHICH originators are returned — they produced at least one loan there — and never change WHAT is summed here. Since the list sorts by `volume` descending by default, a geo-filtered search ranks originators by NATIONAL production, so the top row can be many times larger than that originator's production inside the filtered area. For production INSIDE the geography this request names, read `scopedVolume`/`scopedUnits` on the same row, and sort by them to rank originators by it. `POST /originators/{nmlsId}/breakdowns/counties` (or `/cities`, `/states`, `/zip-codes`) breaks ONE originator's production out by market.","nullable":true,"type":"number"}},"required":["id"],"type":"object"},"OriginatorSummaryRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"borrowerStatus":{"$ref":"#/components/schemas/LoanBorrowerStatusFilterValue"},"broker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Broker shop NMLS id (digits only). A broker is a company — resolve a broker name to its NMLS id via instantSearch (or listCompanies)."}]},"buyerEntityType":{"$ref":"#/components/schemas/BooleanFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"conforming":{"$ref":"#/components/schemas/BooleanFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County name (e.g. \"Broward\") or 5-digit FIPS code. Names resolve to FIPS server-side; include a `state` filter to disambiguate."}]},"currentBalance":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated remaining principal balance (~19% populated). Approximate current equity as `homeValue` (AVM) minus this."}]},"employer":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Employer/company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Point-in-time equity recorded on the loan (sparse, ~10%). NOT a live current-equity figure. For HELOC/cash-out targeting on up-to-date equity, use properties search (listProperties) instead — its equity is far better populated and current."}]},"excludeBroker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans brokered by this broker-shop NMLS id (digits only) — the inverse of `broker`."}]},"excludeCity":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this city — the inverse of `city`."}]},"excludeLender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans from this lender ID (\"everyone but X\") — the inverse of `lender`, same id contract (resolve via instantSearch/listLenders). Loans with no lender stay in the results."}]},"excludeLoanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans funded by this company NMLS id (digits only) — the inverse of `loanCompany`."}]},"excludeOriginator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans with this originator NMLS id (digits only) — the inverse of `originator`. Common for 'everyone but my own shop' lists."}]},"excludeState":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this state (2-letter code, e.g. \"CA\") — the inverse of `state`. For \"everywhere but this state\" lists."}]},"excludeZipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this ZIP code — the inverse of `zipCode`."}]},"fips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exact 5-digit county FIPS code (no name resolution) — the code-only escape hatch alongside `county`."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"homeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"AVM (automated valuation) at the linked property (~26%, MLS-linked). Pair with `currentBalance` to approximate current equity."}]},"includeUnknownOriginator":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Include loans that have no originator NMLS id. Omitted/false (default): such loans are excluded — the vast majority are pre-2016 public records with no linkable originator. true: include them. Note that the default scopes results to loans with a known originator (~2016+ recordings)."}]},"interestRate":{"$ref":"#/components/schemas/NumericFilterValue"},"lender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender ID — the normalized lender-dictionary key, NOT a fuzzy name match. Resolve a lender via instantSearch (or listLenders) and pass the `id` it returns (e.g. \"mortgage_rocket\" or \"mortgage rocket\"). Underscores and letter case are normalized, so either id surface works. A stored normalized lender name (what the `slice: \"lender\"` chart buckets emit) is also accepted, so a chart bucket key filters directly. A value that is neither returns 400 rather than silently matching nothing — to search by lender NAME, use `lenderName`."}]},"lenderName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender name as recorded on the loan document — fuzzy, all-terms match (e.g. \"Fifth Third\"). The name counterpart to the exact-id `lender` filter; use `lender` when you have a resolved id, and this when you only have a name."}]},"loanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Funding/loan company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"loanType":{"$ref":"#/components/schemas/LoanTypeFilterValue"},"ltvAtOrigination":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan-to-value at ORIGINATION (sparse). This is not a current LTV — there is no stored current-LTV field on loans."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"mortgageDate":{"$ref":"#/components/schemas/DateFilterValue"},"originator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Loan originator NMLS id (digits only). To search by name use `originatorName`, or resolve a name to its id via instantSearch."}]},"originatorName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (same originator can return wildly different counts by name string). Resolve the loan officer via instantSearch and filter by `originator` (exact NMLS id) instead. Still functional for now."}]},"saleDate":{"$ref":"#/components/schemas/DateFilterValue"},"salePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"transactionType":{"$ref":"#/components/schemas/LoanTransactionTypeFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zipCode` — same ZIP filter, accepted for cross-entity key parity."}]},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"nmlsId":{"type":"string"},"nmlsIds":{"items":{"type":"string"},"type":"array"},"period":{"$ref":"#/components/schemas/Period"}},"type":"object"},"OriginatorTimeSeriesRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"additionalProperties":false,"properties":{"borrowerStatus":{"$ref":"#/components/schemas/LoanBorrowerStatusFilterValue"},"broker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Broker shop NMLS id (digits only). A broker is a company — resolve a broker name to its NMLS id via instantSearch (or listCompanies)."}]},"buyerEntityType":{"$ref":"#/components/schemas/BooleanFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"conforming":{"$ref":"#/components/schemas/BooleanFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County name (e.g. \"Broward\") or 5-digit FIPS code. Names resolve to FIPS server-side; include a `state` filter to disambiguate."}]},"currentBalance":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated remaining principal balance (~19% populated). Approximate current equity as `homeValue` (AVM) minus this."}]},"employer":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Employer/company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Point-in-time equity recorded on the loan (sparse, ~10%). NOT a live current-equity figure. For HELOC/cash-out targeting on up-to-date equity, use properties search (listProperties) instead — its equity is far better populated and current."}]},"excludeBroker":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans brokered by this broker-shop NMLS id (digits only) — the inverse of `broker`."}]},"excludeCity":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this city — the inverse of `city`."}]},"excludeLender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans from this lender ID (\"everyone but X\") — the inverse of `lender`, same id contract (resolve via instantSearch/listLenders). Loans with no lender stay in the results."}]},"excludeLoanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans funded by this company NMLS id (digits only) — the inverse of `loanCompany`."}]},"excludeOriginator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans with this originator NMLS id (digits only) — the inverse of `originator`. Common for 'everyone but my own shop' lists."}]},"excludeState":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this state (2-letter code, e.g. \"CA\") — the inverse of `state`. For \"everywhere but this state\" lists."}]},"excludeZipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exclude loans in this ZIP code — the inverse of `zipCode`."}]},"fips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Exact 5-digit county FIPS code (no name resolution) — the code-only escape hatch alongside `county`."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"homeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"AVM (automated valuation) at the linked property (~26%, MLS-linked). Pair with `currentBalance` to approximate current equity."}]},"includeUnknownOriginator":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Include loans that have no originator NMLS id. Omitted/false (default): such loans are excluded — the vast majority are pre-2016 public records with no linkable originator. true: include them. Note that the default scopes results to loans with a known originator (~2016+ recordings)."}]},"interestRate":{"$ref":"#/components/schemas/NumericFilterValue"},"lender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender ID — the normalized lender-dictionary key, NOT a fuzzy name match. Resolve a lender via instantSearch (or listLenders) and pass the `id` it returns (e.g. \"mortgage_rocket\" or \"mortgage rocket\"). Underscores and letter case are normalized, so either id surface works. A stored normalized lender name (what the `slice: \"lender\"` chart buckets emit) is also accepted, so a chart bucket key filters directly. A value that is neither returns 400 rather than silently matching nothing — to search by lender NAME, use `lenderName`."}]},"lenderName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender name as recorded on the loan document — fuzzy, all-terms match (e.g. \"Fifth Third\"). The name counterpart to the exact-id `lender` filter; use `lender` when you have a resolved id, and this when you only have a name."}]},"loanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Funding/loan company NMLS id (digits only). Resolve a company name to its NMLS id via instantSearch."}]},"loanType":{"$ref":"#/components/schemas/LoanTypeFilterValue"},"ltvAtOrigination":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan-to-value at ORIGINATION (sparse). This is not a current LTV — there is no stored current-LTV field on loans."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"mortgageDate":{"$ref":"#/components/schemas/DateFilterValue"},"originator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Loan originator NMLS id (digits only). To search by name use `originatorName`, or resolve a name to its id via instantSearch."}]},"originatorName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (same originator can return wildly different counts by name string). Resolve the loan officer via instantSearch and filter by `originator` (exact NMLS id) instead. Still functional for now."}]},"saleDate":{"$ref":"#/components/schemas/DateFilterValue"},"salePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"transactionType":{"$ref":"#/components/schemas/LoanTransactionTypeFilterValue"},"zip":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Alias of `zipCode` — same ZIP filter, accepted for cross-entity key parity."}]},"zipCode":{"$ref":"#/components/schemas/TextFilterValue"}},"type":"object"},"interval":{"$ref":"#/components/schemas/Interval"},"measure":{"$ref":"#/components/schemas/Measure"},"nmlsId":{"type":"string"},"nmlsIds":{"items":{"type":"string"},"type":"array"},"period":{"$ref":"#/components/schemas/Period"},"segment":{"$ref":"#/components/schemas/OriginatorSlice"}},"type":"object"},"OriginatorTransactionTypeFilterValue":{"anyOf":[{"description":"One of (case-insensitive): purchase, refinance, construction, equity, UNKNOWN","enum":["purchase","refinance","construction","equity","UNKNOWN"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): purchase, refinance, construction, equity, UNKNOWN","enum":["purchase","refinance","construction","equity","UNKNOWN"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"Pagination":{"properties":{"cursor":{"description":"Opaque cursor from previous response for next page","type":"string"},"size":{"description":"Page size (1-100, default 25)","example":25,"maximum":100,"minimum":1,"type":"integer"}},"type":"object"},"PayloadTooLarge":{"properties":{"error":{"type":"string"},"limit":{"type":"number"},"size":{"type":"number"}},"required":["error","size","limit"],"type":"object"},"Period":{"enum":["2017","2018","2019","2020","2021","2022","2023","2024","2025","2026","last3Months","last6Months","last12Months","last14Months","last16Months","last18Months","last24Months","yearToDate","allTime"],"type":"string"},"PreviewAlertsRequest":{"properties":{"detectors":{"description":"Limit to specific triggers; all six when omitted.","items":{"enum":["area_new_listing","watched_agent_pending","borrower_listed","epo_risk","agent_sale_closed","rate_term_refi_area","watched_sale","watched_property","watched_loan"],"type":"string"},"type":"array"}},"type":"object"},"PropertyAnalyticsFlatFilters":{"additionalProperties":false,"properties":{"activeLoanCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mortgages believed to still be outstanding (e.g. `{lte: 0}` for parcels with none). `{lte: 0}` alone is NOT a free-and-clear filter: it also matches recently-sold parcels whose new mortgage has not been recorded yet. Pair it with `preSaleLoanCount: {lte: 0}` for parcels we can actually verify."}]},"address":{"$ref":"#/components/schemas/TextFilterValue"},"affordableHousingTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a qualified census tract for affordable-housing programs (17,603,810 parcels). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"agentUid":{"$ref":"#/components/schemas/TextFilterValue"},"apn":{"$ref":"#/components/schemas/TextFilterValue"},"avmConfidence":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Confidence in the value estimate, as a 50–100 score (e.g. `{gte: 90}` for high-confidence estimates only). NOT a fraction — `{gte: 0.9}` matches every scored parcel, not the top decile."}]},"avmValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Automated value estimate for the parcel, in whole dollars (e.g. `{gte: 500000}`). ~77% coverage. Matches the `avm.mid` value on the response."}]},"beds":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Bedroom count (e.g. `{lte: 2}` for starter homes). ~46% coverage — on the rest the bedroom count was never recorded, which is NOT the same as a parcel with no bedrooms and NOT the same as a parcel with no assessor record: 15.6M of them do carry a recorded bath count and floor area. Unrecorded parcels are EXCLUDED by default; pass `includeNulls: true` to add them back. `beds: 0` matches nothing (an unrecorded count is not a count of zero, and a genuine studio is indistinguishable from it), and the response returns `null` rather than `0`."}]},"borrowerStatus":{"$ref":"#/components/schemas/PropertyBorrowerStatusFilterValue"},"brokerNmls":{"$ref":"#/components/schemas/TextFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"companyNmls":{"$ref":"#/components/schemas/TextFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County, as a 5-digit FIPS code (e.g. `06037`). Canonical key for the county dimension; `fips` is the exact-code alias kept for back-compat."}]},"difficultDevelopmentArea":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a HUD-designated difficult development area (30,643,419 parcels). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"distressedTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a distressed-or-underserved nonmetropolitan middle-income tract (13,289,914 parcels). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated equity, in whole dollars (e.g. `{gte: 250000}`). Negative values are genuine underwater parcels. Derived from the value estimate minus outstanding loan balances, so it inherits their coverage (~77%) AND their gaps: on a parcel whose mortgage is missing from the record there is nothing to subtract, so this returns the full value estimate. Pair a high-equity range with `preSaleLoanCount: {lte: 0}` to drop those."}]},"equityPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated equity as a FRACTION of the value estimate, where `1` = the whole value and `0.5` = half. Pass `{gte: 0.5}` for 50%-or-more equity — `{gte: 50}` is not a synonym and matches ZERO parcels, since no value exceeds 1. Negative values are genuine underwater parcels. Note the contrast with `loanLtv`, which takes whole percents. CAUTION: `1` is not proof a parcel is owned free and clear — it is also what a recently-sold parcel returns when the buyer's new mortgage has not been recorded yet, because the calculation subtracts nothing. Add `preSaleLoanCount: {lte: 0}` to restrict to parcels whose position we can actually verify."}]},"fips":{"$ref":"#/components/schemas/TextFilterValue"},"floodHazardTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a FEMA special flood hazard area (4,675,160 parcels). `tractFloodZone` gives the specific zone code. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"foreclosureStatus":{"$ref":"#/components/schemas/PropertyForeclosureStatusFilterValue"},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"lastSalePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"lenderNmls":{"$ref":"#/components/schemas/TextFilterValue"},"loNmls":{"$ref":"#/components/schemas/TextFilterValue"},"loanCount":{"$ref":"#/components/schemas/NumericFilterValue"},"lotSquareFeet":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Lot size in square feet (e.g. `{gte: 5000}`). ~85% coverage; unmeasured parcels are excluded by default — pass `includeNulls: true` to add them back. `lotSquareFeet: 0` matches nothing (the response returns `null`)."}]},"lowModIncomeTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a low- or moderate-income tract under the Community Reinvestment Act (34,010,153 parcels). `tractIncomeLevel` is the four-way form of the same classification. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"majorityMinorityTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a majority-minority tract (38,745,783 parcels). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"milesToCollege":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Straight-line distance from the parcel to the nearest college, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"milesToSchool":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Straight-line distance from the parcel to the nearest school, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"milesToWorship":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Straight-line distance from the parcel to the nearest place of worship, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageBalance":{"$ref":"#/components/schemas/NumericFilterValue"},"opportunityZone":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a federally designated Opportunity Zone tract (10,277,168 parcels). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"ownerName":{"$ref":"#/components/schemas/TextFilterValue"},"preSaleLoanCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mortgages excluded from `activeLoanCount` because the parcel sold after they were recorded — the seller's loan, assumed paid off at closing. Use it to separate the two meanings of `activeLoanCount: 0`: `{activeLoanCount: {lte: 0}, preSaleLoanCount: {lte: 0}}` returns parcels where nothing was excluded, so the zero is backed by the record; `{activeLoanCount: {lte: 0}, preSaleLoanCount: {gte: 1}}` returns the parcels where it is not. On its own a non-zero value is unremarkable — most recently-sold parcels have one and also carry a current mortgage."}]},"ruralTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a rural tract (29,289,319 parcels). Thinner coverage than the other flags — stamped on 111.9M of 161.1M parcels, and a parcel with no value is dropped by either `true` or `false`. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"saleCount":{"$ref":"#/components/schemas/NumericFilterValue"},"salePropensity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Likelihood the parcel sells in the near term, as a 0–100 score (e.g. `{gte: 80}` for the most likely to sell). NOT a fraction — `{gte: 0.8}` matches nearly every scored parcel. `salePropensityCategory` is the bucketed form of the same signal."}]},"salePropensityCategory":{"$ref":"#/components/schemas/PropertySalePropensityCategoryFilterValue"},"squareFeet":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Building area in square feet (e.g. `{gte: 1500}`). ~68% coverage; unmeasured parcels are excluded by default — pass `includeNulls: true` to add them back. `squareFeet: 0` matches nothing (the response returns `null`)."}]},"state":{"$ref":"#/components/schemas/TextFilterValue"},"tractApplications":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mortgage applications reported in the tract over the year, as a count. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractAsianPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Asian (non-Hispanic) share of the tract's population, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractBlackPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Black (non-Hispanic) share of the tract's population, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractCountyCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Three-digit county FIPS code of the tract (county-within-state, NOT the 5-digit `county`/`fips` key). Pass with `tractStateCode` and `tractId` to pin one neighborhood. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractDenialRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the tract's mortgage applications that were denied, 0-100 (e.g. `{gte: 25}` for 25%+). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractFamilyIncome":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Median family income of the tract, in whole dollars (e.g. `{lte: 60000}`). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractFloodZone":{"$ref":"#/components/schemas/PropertyTractFloodZoneFilterValue"},"tractHispanicPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Hispanic or Latino share of the tract's population, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractHomeownershipRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Owner-occupied share of the tract's housing units, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractHouseholdIncome":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Median household income of the tract, in whole dollars (e.g. `{gte: 120000}`). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractId":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Six-digit tract code. A tract code REPEATS in every state and county, so this only identifies a neighborhood when passed ALONGSIDE `tractStateCode` and `tractCountyCode` — on its own it matches roughly 75× too many parcels. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractIncomeLevel":{"$ref":"#/components/schemas/PropertyTractIncomeLevelFilterValue"},"tractIncomeVsMetroPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Tract income relative to its metro area, where `100` is parity — `{lt: 80}` is the CRA low/moderate band and values legitimately exceed 100 (observed up to 412). NOT a 0-100 share. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractLoanVolume":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mortgage dollar volume reported in the tract over the year, in whole dollars. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractMedianAge":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Median age of the tract's population, in years. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractMedianHomeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Median home value across the tract, in whole dollars. A neighborhood statistic — the parcel's own value estimate is `avmValue`. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractMinorityPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Non-white share of the tract's population, 0-100 (e.g. `{gte: 50}` for majority-minority; `majorityMinorityTract` is the flag form). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractOriginations":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mortgage originations reported in the tract over the year, as a count. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractPopulation":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Total population of the tract. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractPovertyRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the tract's population below the poverty line, 0-100 (e.g. `{gte: 20}` for 20%+). Pass whole percents — `{gte: 0.2}` means 0.2% and matches almost every tract. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractRuralGradient":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Remoteness of the tract on an ORDINAL 1-10 scale (1 = metropolitan core, 10 = most remote). This is a code, not a percent — `{gte: 7}` selects the most remote tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractStateCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Two-digit state FIPS code of the tract. Pass with `tractCountyCode` and `tractId` to pin one neighborhood. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractWhiteNonHispanicPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"White (non-Hispanic) share of the tract's population, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"usdaEligibleTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a tract eligible for USDA rural housing programs (70,637,816 parcels). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"yearBuilt":{"$ref":"#/components/schemas/NumericFilterValue"},"zip":{"$ref":"#/components/schemas/TextFilterValue"},"zipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"ZIP code. Canonical key (matches loans `zipCode` and the response DTO); `zip` is a legacy alias kept for back-compat."}]}},"type":"object"},"PropertyAnalyticsResponse":{"properties":{"avgAvmValue":{"description":"Average AVM value","nullable":true,"type":"number"},"avgEquity":{"description":"Average estimated equity. Excludes values outside -2,000,000 to 50,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","nullable":true,"type":"number"},"excluded":{"description":"Per-measure count of parcels this query's sentinel guard excluded — parcels that carry the field but whose value is an out-of-range fill. Compare against `totalCount` to see what share of the matched population the figure was computed over. Absent for `avgAvmValue`, which is unguarded.","properties":{"avgEquity":{"type":"number"}},"type":"object"},"pctInForeclosure":{"nullable":true,"type":"number"},"totalCount":{"type":"number"}},"required":["totalCount","avgAvmValue","avgEquity","pctInForeclosure"],"type":"object"},"PropertyAvm":{"nullable":true,"properties":{"confidence":{"description":"0–100","nullable":true,"type":"number"},"high":{"nullable":true,"type":"number"},"low":{"nullable":true,"type":"number"},"mid":{"nullable":true,"type":"number"}},"required":["low","mid","high","confidence"],"type":"object"},"PropertyBorrowerStatusFilterValue":{"anyOf":[{"description":"One of (case-insensitive): no_active_loans, Current, Current_via_ALI","enum":["no_active_loans","Current","Current_via_ALI"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): no_active_loans, Current, Current_via_ALI","enum":["no_active_loans","Current","Current_via_ALI"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"PropertyChartRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/PropertyAnalyticsFlatFilters"},"measure":{"$ref":"#/components/schemas/ChartMeasure"},"slice":{"$ref":"#/components/schemas/PropertyChartSlice"}},"required":["slice"],"type":"object"},"PropertyChartSlice":{"enum":["city","county","state","zipCode","zip","foreclosureStatus","borrowerStatus","salePropensityCategory"],"type":"string"},"PropertyCommunityLending":{"description":"Community Lending — the profile of the neighborhood (U.S. Census tract) this parcel sits in: program designations, income and affordability, the population profile, the local mortgage market, remoteness and proximity. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100. Two fields are deliberately NOT 0-100: `tractIncomeVsMetroPct` is a ratio where 100 means parity with the metro (it exceeds 100), and `tractRuralGradient` is an ordinal 1-10 code. `null` — not an all-null object — for the roughly 6% of parcels that resolve to no neighborhood. Every field here is also a filter key on `POST /properties`.","nullable":true,"properties":{"affordableHousingTract":{"description":"A qualified neighborhood for affordable-housing programs. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"boolean"},"difficultDevelopmentArea":{"description":"A HUD-designated difficult development area. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"boolean"},"distressedTract":{"description":"A distressed-or-underserved nonmetropolitan middle-income neighborhood. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"boolean"},"floodHazardTract":{"description":"In a FEMA special flood hazard area. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"boolean"},"lowModIncomeTract":{"description":"A low- or moderate-income neighborhood under the Community Reinvestment Act. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"boolean"},"majorityMinorityTract":{"description":"A majority-minority neighborhood. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"boolean"},"milesToCollege":{"description":"Distance to the nearest college, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"milesToSchool":{"description":"Distance to the nearest school, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"milesToWorship":{"description":"Distance to the nearest place of worship, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"opportunityZone":{"description":"In a federally designated Opportunity Zone. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"boolean"},"ruralTract":{"description":"A rural neighborhood. Thinner coverage than the other designations, so null is common. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"boolean"},"tractApplications":{"description":"Mortgage applications reported over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractAsianPct":{"description":"Asian (non-Hispanic) share of the population. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractBlackPct":{"description":"Black (non-Hispanic) share of the population. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractCountyCode":{"description":"Public three-digit county-within-state code (not the five-digit `fips`). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"string"},"tractDenialRate":{"description":"Share of mortgage applications that were denied. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractFamilyIncome":{"description":"Median family income, in whole dollars. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractFloodZone":{"description":"FEMA flood-zone code (e.g. `AE`). Null means no special flood hazard area on file. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"string"},"tractHispanicPct":{"description":"Hispanic or Latino share of the population. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractHomeownershipRate":{"description":"Owner-occupied share of housing units. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractHouseholdIncome":{"description":"Median household income, in whole dollars. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractId":{"description":"Public six-digit neighborhood code. It repeats in every state and county, so it identifies a neighborhood only together with `tractStateCode` and `tractCountyCode`. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"string"},"tractIncomeLevel":{"description":"Relative-income classification of the neighborhood: low, moderate, middle or upper. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","enum":["low","moderate","middle","upper",null],"nullable":true,"type":"string"},"tractIncomeVsMetroPct":{"description":"Neighborhood income relative to its metro area, where 100 is parity. Legitimately exceeds 100 — this is a ratio, not a share. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractLoanVolume":{"description":"Mortgage dollar volume reported over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractMedianAge":{"description":"Median age, in years. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractMedianHomeValue":{"description":"Median home value across the neighborhood, in whole dollars — a neighborhood statistic, not this parcel's value estimate (see `avm`). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractMinorityPct":{"description":"Non-white share of the population. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractOriginations":{"description":"Mortgage originations reported over the year. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractPopulation":{"description":"Total population. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractPovertyRate":{"description":"Share of the population below the poverty line. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractRuralGradient":{"description":"Remoteness on an ordinal 1-10 scale (1 = metropolitan core, 10 = most remote). A code, not a percent. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"tractStateCode":{"description":"Public two-digit state code. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"string"},"tractWhiteNonHispanicPct":{"description":"White (non-Hispanic) share of the population. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"number"},"usdaEligibleTract":{"description":"Eligible for USDA rural housing programs. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100.","nullable":true,"type":"boolean"}},"required":["opportunityZone","majorityMinorityTract","lowModIncomeTract","distressedTract","usdaEligibleTract","ruralTract","difficultDevelopmentArea","affordableHousingTract","floodHazardTract","tractIncomeLevel","tractFamilyIncome","tractHouseholdIncome","tractIncomeVsMetroPct","tractPovertyRate","tractMinorityPct","tractPopulation","tractMedianAge","tractMedianHomeValue","tractHomeownershipRate","tractHispanicPct","tractBlackPct","tractAsianPct","tractWhiteNonHispanicPct","tractOriginations","tractApplications","tractLoanVolume","tractDenialRate","tractRuralGradient","tractFloodZone","milesToSchool","milesToCollege","milesToWorship","tractId","tractStateCode","tractCountyCode"],"type":"object"},"PropertyDetail":{"allOf":[{"$ref":"#/components/schemas/PropertySummary"},{"properties":{"communityLending":{"$ref":"#/components/schemas/PropertyCommunityLending"},"enrichment":{"description":"Owner contact enrichment data (included if previously enriched by the authenticated user)","nullable":true,"properties":{"enrichedAt":{"description":"ISO 8601 timestamp","type":"string"},"persons":{"items":{"$ref":"#/components/schemas/SkipTracePerson"},"type":"array"},"source":{"description":"Data source identifier","type":"string"}},"required":["persons","enrichedAt","source"],"type":"object"},"foreclosureDetail":{"nullable":true,"properties":{"beneficiaryLender":{"nullable":true,"type":"string"},"count":{"nullable":true,"type":"number"},"latestCode":{"nullable":true,"type":"string"},"latestDate":{"nullable":true,"type":"string"},"trusteeSaleNumber":{"nullable":true,"type":"string"},"unpaidBalance":{"nullable":true,"type":"number"}},"required":["count","latestCode","latestDate","beneficiaryLender","trusteeSaleNumber","unpaidBalance"],"type":"object"},"ownerMailingAddress":{"nullable":true,"properties":{"city":{"nullable":true,"type":"string"},"state":{"nullable":true,"type":"string"},"street":{"nullable":true,"type":"string"},"zip":{"nullable":true,"type":"string"}},"required":["street","city","state","zip"],"type":"object"},"owners":{"description":"Every owner of record — `owners[0]` is the same person the flat `ownerName`/`ownerFirstName`/`ownerLastName` fields describe, and the rest are co-owners/co-borrowers. Additive: those three fields are unchanged. `null` (never `[]`) when the parcel has no readable owner.","items":{"$ref":"#/components/schemas/PropertyOwner"},"nullable":true,"type":"array"},"parties":{"$ref":"#/components/schemas/PropertyParties"},"position":{"properties":{"activeOverFive":{"nullable":true,"type":"boolean"},"loanCountActive":{"nullable":true,"type":"number"},"loanCountAll":{"nullable":true,"type":"number"},"loanCountPaidOff":{"nullable":true,"type":"number"},"loanCountPreSale":{"description":"Mortgages excluded because the parcel sold after they were recorded. Same value as the summary's `preSaleLoanCount`. These four counts partition `loanCountAll`.","nullable":true,"type":"number"},"loanCountReleased":{"description":"Mortgages with a recorded release — documented evidence of a payoff, unlike `loanCountPreSale`.","nullable":true,"type":"number"},"sumOutstanding":{"nullable":true,"type":"number"}},"required":["loanCountAll","loanCountActive","loanCountPaidOff","loanCountReleased","loanCountPreSale","sumOutstanding","activeOverFive"],"type":"object"},"relationships":{"$ref":"#/components/schemas/PropertyRelationships"}},"type":"object"}]},"PropertyDetailResponse":{"properties":{"alternates":{"description":"Sibling document `id`s when `ambiguousRef` is true — pass one back as `/{id}` to fetch that exact unit. Absent on an unambiguous lookup.","items":{"type":"string"},"type":"array"},"ambiguousRef":{"description":"`true` only when the id you passed resolved to more than one parcel (a non-unique `mm_property_id` colliding across units). `data` is a deterministic pick (the base parcel); use `alternates` to re-request a specific sibling by its exact `id`. Absent on an unambiguous lookup.","type":"boolean"},"data":{"$ref":"#/components/schemas/PropertyDetail"}},"required":["data"],"type":"object"},"PropertyEnrichment":{"properties":{"enrichedAt":{"description":"ISO 8601 timestamp","type":"string"},"persons":{"items":{"$ref":"#/components/schemas/SkipTracePerson"},"type":"array"},"source":{"description":"Data source identifier","type":"string"}},"required":["persons","enrichedAt","source"],"type":"object"},"PropertyEquity":{"nullable":true,"properties":{"pct":{"description":"Equity as a FRACTION of the value estimate — `1` is the whole value, `0.5` is half. A `1` alongside `activeLoanCountKnown: false` is arithmetic on a missing mortgage, not a free-and-clear parcel.","nullable":true,"type":"number"},"value":{"description":"Estimated equity in whole dollars — the value estimate minus the outstanding balance of the mortgages we know about. It inherits their completeness: when `activeLoanCountKnown` is `false` there is no known balance to subtract, so this equals the full value estimate and should NOT be read as equity.","nullable":true,"type":"number"}},"required":["value","pct"],"type":"object"},"PropertyField":{"enum":["address","city","state","zipCode","zip","apn","fips","ownerName","beds","squareFeet","lotSquareFeet","yearBuilt","avmValue","avmConfidence","equity","equityPct","salePropensity","salePropensityCategory","foreclosureStatus","borrowerStatus","loanCount","activeLoanCount","mortgageBalance","saleCount","lastSalePrice","loNmls","lenderNmls","companyNmls","brokerNmls","agentUid"],"type":"string"},"PropertyFlatFilters":{"additionalProperties":false,"properties":{"activeLoanCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mortgages believed to still be outstanding (e.g. `{lte: 0}` for parcels with none). `{lte: 0}` alone is NOT a free-and-clear filter: it also matches recently-sold parcels whose new mortgage has not been recorded yet. Pair it with `preSaleLoanCount: {lte: 0}` for parcels we can actually verify."}]},"address":{"$ref":"#/components/schemas/TextFilterValue"},"affordableHousingTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a qualified census tract for affordable-housing programs (17,603,810 parcels). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"agentUid":{"$ref":"#/components/schemas/TextFilterValue"},"apn":{"$ref":"#/components/schemas/TextFilterValue"},"avmConfidence":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Confidence in the value estimate, as a 50–100 score (e.g. `{gte: 90}` for high-confidence estimates only). NOT a fraction — `{gte: 0.9}` matches every scored parcel, not the top decile."}]},"avmValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Automated value estimate for the parcel, in whole dollars (e.g. `{gte: 500000}`). ~77% coverage. Matches the `avm.mid` value on the response."}]},"beds":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Bedroom count (e.g. `{lte: 2}` for starter homes). ~46% coverage — on the rest the bedroom count was never recorded, which is NOT the same as a parcel with no bedrooms and NOT the same as a parcel with no assessor record: 15.6M of them do carry a recorded bath count and floor area. Unrecorded parcels are EXCLUDED by default; pass `includeNulls: true` to add them back. `beds: 0` matches nothing (an unrecorded count is not a count of zero, and a genuine studio is indistinguishable from it), and the response returns `null` rather than `0`."}]},"borrowerStatus":{"$ref":"#/components/schemas/PropertyBorrowerStatusFilterValue"},"brokerNmls":{"$ref":"#/components/schemas/TextFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"companyNmls":{"$ref":"#/components/schemas/TextFilterValue"},"county":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"County, as a 5-digit FIPS code (e.g. `06037`). Canonical key for the county dimension; `fips` is the exact-code alias kept for back-compat."}]},"difficultDevelopmentArea":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a HUD-designated difficult development area (30,643,419 parcels). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"distressedTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a distressed-or-underserved nonmetropolitan middle-income tract (13,289,914 parcels). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"equity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated equity, in whole dollars (e.g. `{gte: 250000}`). Negative values are genuine underwater parcels. Derived from the value estimate minus outstanding loan balances, so it inherits their coverage (~77%) AND their gaps: on a parcel whose mortgage is missing from the record there is nothing to subtract, so this returns the full value estimate. Pair a high-equity range with `preSaleLoanCount: {lte: 0}` to drop those."}]},"equityPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Estimated equity as a FRACTION of the value estimate, where `1` = the whole value and `0.5` = half. Pass `{gte: 0.5}` for 50%-or-more equity — `{gte: 50}` is not a synonym and matches ZERO parcels, since no value exceeds 1. Negative values are genuine underwater parcels. Note the contrast with `loanLtv`, which takes whole percents. CAUTION: `1` is not proof a parcel is owned free and clear — it is also what a recently-sold parcel returns when the buyer's new mortgage has not been recorded yet, because the calculation subtracts nothing. Add `preSaleLoanCount: {lte: 0}` to restrict to parcels whose position we can actually verify."}]},"fips":{"$ref":"#/components/schemas/TextFilterValue"},"floodHazardTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a FEMA special flood hazard area (4,675,160 parcels). `tractFloodZone` gives the specific zone code. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"foreclosureStatus":{"$ref":"#/components/schemas/PropertyForeclosureStatusFilterValue"},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"lastSalePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"lenderNmls":{"$ref":"#/components/schemas/TextFilterValue"},"loNmls":{"$ref":"#/components/schemas/TextFilterValue"},"loanAmount":{"$ref":"#/components/schemas/NumericFilterValue"},"loanBalance":{"$ref":"#/components/schemas/NumericFilterValue"},"loanBorrowerStatus":{"$ref":"#/components/schemas/PropertyLoanBorrowerStatusFilterValue"},"loanCompany":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Per-loan funding-company NMLS id (digits only) on the parcel's loans."}]},"loanCount":{"$ref":"#/components/schemas/NumericFilterValue"},"loanInterestRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Deprecated alias of `loanModeledInterestRate` — a low-biased ModelMatch model that caps near 7%. For the genuine recorded note rate use `recordedInterestRate`."}]},"loanLender":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender ID on the parcel's loans — the normalized lender-dictionary key, NOT the lender name the response shows. Resolve a lender via instantSearch (or listLenders) and pass the `id` it returns (e.g. \"mortgage_rocket\" or \"mortgage rocket\"); the `lenderId` on a parcel's `loans[]` is the same value, so a lender read off a result round-trips here directly. Underscores and letter case are normalized, and the id expands to every stored variant the lender is recorded under. A value that is neither an id nor a stored lender name returns 400 with the closest matches, rather than silently matching nothing — to filter by the lender NAME shown on the parcel, use `loanLenderName`."}]},"loanLenderName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Lender NAME on the parcel's loans — the counterpart to the exact-id `loanLender`, and the filter that accepts the `lenderName` a parcel's `loans[]` displays (e.g. \"UNION HOME MORTGAGE CORP\"). Case-insensitive, matched against the name recorded on the loan. When the name is one the lender dictionary knows, it also expands to that lender's whole recorded-name family, so a brand name (\"union home mortgage\") selects far more than the one literal string. Never 400s: a name it cannot resolve simply matches the recorded string. The response reports how each value resolved as `lenderNormalizations`."}]},"loanLtv":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Loan-to-value on the parcel's active loan(s), as WHOLE PERCENTS — `{gte: 40, lte: 50}` means 40%–50% LTV. A fractional range (`{gte: 0.4, lte: 0.5}`) is not a synonym and matches ZERO parcels. ~7% coverage. Careful: the response DTO reports the same measurement as a fraction (`loans[].ltv` of `0.4238` is 42.38% LTV), so a value read off a result must be multiplied by 100 before it can be used here. `equityPct`, by contrast, takes the fraction."}]},"loanMatchMode":{"description":"How the loan-slot filters combine across a parcel's 5 cached loans. `correlated` (default): ONE loan (any slot) must satisfy ALL loan-slot conditions. `most_recent`: only the newest loan (loan_1). `any`: each condition may be satisfied by a different loan. `none`: ignore loan-slot filters. Honored on list, bulk-delivery, and bulk-enrich.","enum":["correlated","most_recent","any","none"],"type":"string"},"loanModeledInterestRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Per-loan MODELED rate (`loan_N.modeled_interest_rate`). Low-biased, effectively caps near 7% — not a note rate. Use `recordedInterestRate` for the recorded rate."}]},"loanOriginator":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Per-loan originator NMLS id (digits only) on the parcel's loans. For all-time attribution across the parcel use `loNmls`."}]},"loanOriginatorName":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"deprecated":true,"description":"DEPRECATED — fuzzy name matching is unreliable (same originator can return wildly different counts by name string). Resolve the loan officer via instantSearch and filter by `loanOriginator` (exact NMLS id) instead. Still functional for now."}]},"loanRecordedDate":{"$ref":"#/components/schemas/DateFilterValue"},"loanTransactionType":{"$ref":"#/components/schemas/PropertyLoanTransactionTypeFilterValue"},"loanType":{"$ref":"#/components/schemas/PropertyLoanTypeFilterValue"},"lotSquareFeet":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Lot size in square feet (e.g. `{gte: 5000}`). ~85% coverage; unmeasured parcels are excluded by default — pass `includeNulls: true` to add them back. `lotSquareFeet: 0` matches nothing (the response returns `null`)."}]},"lowModIncomeTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a low- or moderate-income tract under the Community Reinvestment Act (34,010,153 parcels). `tractIncomeLevel` is the four-way form of the same classification. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"majorityMinorityTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a majority-minority tract (38,745,783 parcels). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"milesToCollege":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Straight-line distance from the parcel to the nearest college, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"milesToSchool":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Straight-line distance from the parcel to the nearest school, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"milesToWorship":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Straight-line distance from the parcel to the nearest place of worship, in miles. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"mode":{"enum":["and","or"],"type":"string"},"mortgageBalance":{"$ref":"#/components/schemas/NumericFilterValue"},"opportunityZone":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a federally designated Opportunity Zone tract (10,277,168 parcels). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"ownerName":{"$ref":"#/components/schemas/TextFilterValue"},"preSaleLoanCount":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mortgages excluded from `activeLoanCount` because the parcel sold after they were recorded — the seller's loan, assumed paid off at closing. Use it to separate the two meanings of `activeLoanCount: 0`: `{activeLoanCount: {lte: 0}, preSaleLoanCount: {lte: 0}}` returns parcels where nothing was excluded, so the zero is backed by the record; `{activeLoanCount: {lte: 0}, preSaleLoanCount: {gte: 1}}` returns the parcels where it is not. On its own a non-zero value is unremarkable — most recently-sold parcels have one and also carry a current mortgage."}]},"programEligibility":{"description":"Restrict to parcels whose value estimate falls within this loan program's county price limit — an eligibility band (value ceiling). Pair with `fips` to resolve the county's limit; with no county context the national baseline applies. Parcels without a value estimate are excluded. This is a price band only — no borrower income, payment, or DTI is considered.","enum":["fha","conforming"],"type":"string"},"recordedInterestRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Genuine RECORDED note rate from the parcel's active loan(s) (~7% coverage, concentrated on the most-recent loan). Percent input (e.g. 7 means 7%)."}]},"ruralTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a rural tract (29,289,319 parcels). Thinner coverage than the other flags — stamped on 111.9M of 161.1M parcels, and a parcel with no value is dropped by either `true` or `false`. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"saleCount":{"$ref":"#/components/schemas/NumericFilterValue"},"salePropensity":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Likelihood the parcel sells in the near term, as a 0–100 score (e.g. `{gte: 80}` for the most likely to sell). NOT a fraction — `{gte: 0.8}` matches nearly every scored parcel. `salePropensityCategory` is the bucketed form of the same signal."}]},"salePropensityCategory":{"$ref":"#/components/schemas/PropertySalePropensityCategoryFilterValue"},"squareFeet":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Building area in square feet (e.g. `{gte: 1500}`). ~68% coverage; unmeasured parcels are excluded by default — pass `includeNulls: true` to add them back. `squareFeet: 0` matches nothing (the response returns `null`)."}]},"state":{"$ref":"#/components/schemas/TextFilterValue"},"tractApplications":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mortgage applications reported in the tract over the year, as a count. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractAsianPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Asian (non-Hispanic) share of the tract's population, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractBlackPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Black (non-Hispanic) share of the tract's population, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractCountyCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Three-digit county FIPS code of the tract (county-within-state, NOT the 5-digit `county`/`fips` key). Pass with `tractStateCode` and `tractId` to pin one neighborhood. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractDenialRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the tract's mortgage applications that were denied, 0-100 (e.g. `{gte: 25}` for 25%+). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractFamilyIncome":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Median family income of the tract, in whole dollars (e.g. `{lte: 60000}`). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractFloodZone":{"$ref":"#/components/schemas/PropertyTractFloodZoneFilterValue"},"tractHispanicPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Hispanic or Latino share of the tract's population, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractHomeownershipRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Owner-occupied share of the tract's housing units, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractHouseholdIncome":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Median household income of the tract, in whole dollars (e.g. `{gte: 120000}`). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractId":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Six-digit tract code. A tract code REPEATS in every state and county, so this only identifies a neighborhood when passed ALONGSIDE `tractStateCode` and `tractCountyCode` — on its own it matches roughly 75× too many parcels. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractIncomeLevel":{"$ref":"#/components/schemas/PropertyTractIncomeLevelFilterValue"},"tractIncomeVsMetroPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Tract income relative to its metro area, where `100` is parity — `{lt: 80}` is the CRA low/moderate band and values legitimately exceed 100 (observed up to 412). NOT a 0-100 share. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractLoanVolume":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mortgage dollar volume reported in the tract over the year, in whole dollars. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractMedianAge":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Median age of the tract's population, in years. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractMedianHomeValue":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Median home value across the tract, in whole dollars. A neighborhood statistic — the parcel's own value estimate is `avmValue`. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractMinorityPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Non-white share of the tract's population, 0-100 (e.g. `{gte: 50}` for majority-minority; `majorityMinorityTract` is the flag form). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractOriginations":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Mortgage originations reported in the tract over the year, as a count. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractPopulation":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Total population of the tract. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractPovertyRate":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Share of the tract's population below the poverty line, 0-100 (e.g. `{gte: 20}` for 20%+). Pass whole percents — `{gte: 0.2}` means 0.2% and matches almost every tract. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractRuralGradient":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"Remoteness of the tract on an ORDINAL 1-10 scale (1 = metropolitan core, 10 = most remote). This is a code, not a percent — `{gte: 7}` selects the most remote tracts. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractStateCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"Two-digit state FIPS code of the tract. Pass with `tractCountyCode` and `tractId` to pin one neighborhood. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"tractWhiteNonHispanicPct":{"allOf":[{"$ref":"#/components/schemas/NumericFilterValue"},{"description":"White (non-Hispanic) share of the tract's population, 0-100. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"usdaEligibleTract":{"allOf":[{"$ref":"#/components/schemas/BooleanFilterValue"},{"description":"Parcel sits in a tract eligible for USDA rural housing programs (70,637,816 parcels). Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100."}]},"yearBuilt":{"$ref":"#/components/schemas/NumericFilterValue"},"zip":{"$ref":"#/components/schemas/TextFilterValue"},"zipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"ZIP code. Canonical key (matches loans `zipCode` and the response DTO); `zip` is a legacy alias kept for back-compat."}]}},"type":"object"},"PropertyForeclosure":{"properties":{"matched":{"type":"boolean"},"scheduledAuctionDate":{"nullable":true,"type":"string"},"status":{"description":"e.g. \"in_foreclosure\" or \"unknown\"","nullable":true,"type":"string"}},"required":["matched","status","scheduledAuctionDate"],"type":"object"},"PropertyForeclosureStatusFilterValue":{"anyOf":[{"description":"One of (case-insensitive): unknown, in_foreclosure","enum":["unknown","in_foreclosure"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): unknown, in_foreclosure","enum":["unknown","in_foreclosure"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"PropertyLastPartyRoster":{"description":"The most recent loan's originator(s). Deliberately originator-only — see the parent description.","properties":{"originators":{"items":{"type":"string"},"type":"array"}},"required":["originators"],"type":"object"},"PropertyListRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/PropertyFlatFilters"},"pagination":{"$ref":"#/components/schemas/Pagination"},"sort":{"items":{"properties":{"field":{"$ref":"#/components/schemas/PropertyField"},"order":{"$ref":"#/components/schemas/SortOrder"}},"required":["field"],"type":"object"},"type":"array"}},"type":"object"},"PropertyListResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/PropertySummary"},"type":"array"},"lenderNormalizations":{"description":"How each `loanLenderName` value resolved against the lender dictionary. Present when a `loanLenderName` filter was supplied. A `matchedVia` of `unresolved` means only the recorded lender string was matched, not the lender's whole name family.","items":{"$ref":"#/components/schemas/LenderNormalization"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"PropertyLoan":{"properties":{"amount":{"nullable":true,"type":"number"},"borrowerStatus":{"nullable":true,"type":"string"},"brokerNmls":{"nullable":true,"type":"string"},"companyNmls":{"nullable":true,"type":"string"},"currentBalance":{"nullable":true,"type":"number"},"interestRate":{"nullable":true,"type":"number"},"lenderId":{"description":"Lender id for this loan — pass it back as `loanLender` to select every parcel financed by the same lender, exactly as a chart bucket's `id` round-trips. `null` when this loan carries no lender id; use `lenderName` with `loanLenderName` in that case.","nullable":true,"type":"string"},"lenderName":{"description":"Lender name as recorded on the loan document — the same value `/v1/loans` returns as `lenderName` for this loan. To filter parcels by it, pass it as `loanLenderName`; `lenderId` is the exact-id route.","nullable":true,"type":"string"},"lenderNmls":{"nullable":true,"type":"string"},"loanType":{"nullable":true,"type":"string"},"ltv":{"nullable":true,"type":"number"},"originatorName":{"nullable":true,"type":"string"},"originatorNmls":{"nullable":true,"type":"string"},"recordedInterestRate":{"nullable":true,"type":"number"},"recordingDate":{"nullable":true,"type":"string"},"transactionType":{"nullable":true,"type":"string"}},"required":["amount","currentBalance","interestRate","recordedInterestRate","loanType","transactionType","ltv","recordingDate","borrowerStatus","lenderNmls","lenderName","lenderId","originatorNmls","originatorName","brokerNmls","companyNmls"],"type":"object"},"PropertyLoanBorrowerStatusFilterValue":{"anyOf":[{"description":"One of (case-insensitive): Current, Current_via_ALI","enum":["Current","Current_via_ALI"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): Current, Current_via_ALI","enum":["Current","Current_via_ALI"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"PropertyLoanTransactionTypeFilterValue":{"anyOf":[{"description":"One of (case-insensitive): purchase, refinance, equity, construction","enum":["purchase","refinance","equity","construction"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): purchase, refinance, equity, construction","enum":["purchase","refinance","equity","construction"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"PropertyLoanTypeFilterValue":{"anyOf":[{"description":"One of (case-insensitive): va, fha, conventional","enum":["va","fha","conventional"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): va, fha, conventional","enum":["va","fha","conventional"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"PropertyOwner":{"properties":{"firstName":{"nullable":true,"type":"string"},"fullName":{"description":"Per-owner composed display name; null when the record came from the assessment slots, which have no composed form.","nullable":true,"type":"string"},"lastName":{"nullable":true,"type":"string"},"middleName":{"nullable":true,"type":"string"}},"required":["firstName","middleName","lastName","fullName"],"type":"object"},"PropertyParties":{"description":"Mortgage parties attributed to the parcel, split by scope: `alltime` (everyone on record, a strict superset of the rest), `active` (parties on loans still outstanding), `matched` (the subset whose loan resolved to a known NMLS entity) and `last` (the most recent loan). Real estate agents are not part of this block — reach parcels from an agent through `POST /agents/{id}/properties`.","properties":{"active":{"$ref":"#/components/schemas/PropertyPartyRoster"},"alltime":{"$ref":"#/components/schemas/PropertyPartyRoster"},"last":{"$ref":"#/components/schemas/PropertyLastPartyRoster"},"matched":{"$ref":"#/components/schemas/PropertyPartyRoster"}},"required":["alltime","active","matched","last"],"type":"object"},"PropertyPartyRoster":{"description":"NMLS ids of the mortgage parties attributed to the parcel under one scope. Each id resolves through the originator, lender and company detail endpoints.","properties":{"brokers":{"items":{"type":"string"},"type":"array"},"companies":{"items":{"type":"string"},"type":"array"},"lenders":{"items":{"type":"string"},"type":"array"},"originators":{"items":{"type":"string"},"type":"array"}},"required":["originators","lenders","companies","brokers"],"type":"object"},"PropertyRelationships":{"properties":{"agents":{"items":{"type":"string"},"type":"array"},"brokers":{"items":{"type":"string"},"type":"array"},"companies":{"items":{"type":"string"},"type":"array"},"lenders":{"items":{"type":"string"},"type":"array"},"originators":{"items":{"type":"string"},"type":"array"}},"required":["originators","lenders","companies","brokers","agents"],"type":"object"},"PropertySalePropensity":{"nullable":true,"properties":{"category":{"description":"Low/Medium/High","nullable":true,"type":"string"},"score":{"description":"0–100","nullable":true,"type":"number"}},"required":["score","category"],"type":"object"},"PropertySalePropensityCategoryFilterValue":{"anyOf":[{"description":"One of (case-insensitive): High, Medium, Low","enum":["High","Medium","Low"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): High, Medium, Low","enum":["High","Medium","Low"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"PropertySales":{"properties":{"count":{"nullable":true,"type":"number"},"firstDate":{"nullable":true,"type":"string"},"lastDate":{"nullable":true,"type":"string"},"lastPrice":{"nullable":true,"type":"number"}},"required":["count","lastPrice","lastDate","firstDate"],"type":"object"},"PropertySearchRequest":{"properties":{"limit":{"description":"Max results to return (default 12).","maximum":50,"minimum":1,"type":"integer"},"query":{"description":"Free-text search — an address (full or partial), an owner name, or a place. Ranked by relevance; tolerates typos, missing parts, and reordered directionals.","maxLength":200,"minLength":1,"type":"string"}},"required":["query"],"type":"object"},"PropertySummary":{"properties":{"activeLoanCount":{"description":"Mortgages believed to still be outstanding. IMPORTANT: `0` does not always mean the parcel is paid off — on a recently-sold parcel it usually means the buyer's new mortgage has not reached the public record yet, so the honest reading is UNKNOWN. Check `activeLoanCountKnown` before treating a `0` as fact, and do not infer 100% `equity` from it.","nullable":true,"type":"number"},"activeLoanCountKnown":{"description":"`false` when `activeLoanCount` reflects a gap in the record rather than a measurement — the parcel sold, its prior mortgage was excluded, and no replacement has been recorded yet. On those parcels `activeLoanCount: 0`, `mortgageBalance: 0` and an `equity` of 100% are all consequences of the same missing document, not independent findings. To exclude them, filter `preSaleLoanCount: {lte: 0}` alongside `activeLoanCount: {lte: 0}`.","type":"boolean"},"address":{"nullable":true,"type":"string"},"apn":{"description":"Assessor parcel number (cleaned)","nullable":true,"type":"string"},"avm":{"$ref":"#/components/schemas/PropertyAvm"},"baths":{"nullable":true,"type":"number"},"beds":{"nullable":true,"type":"number"},"borrowerStatus":{"nullable":true,"type":"string"},"city":{"nullable":true,"type":"string"},"coordinates":{"nullable":true,"properties":{"lat":{"type":"number"},"lon":{"type":"number"}},"required":["lat","lon"],"type":"object"},"equity":{"$ref":"#/components/schemas/PropertyEquity"},"fips":{"description":"FIPS county code","nullable":true,"type":"string"},"foreclosure":{"$ref":"#/components/schemas/PropertyForeclosure"},"id":{"description":"Document ID","type":"string"},"loanCount":{"description":"Every mortgage on record for this parcel, current or not. Splits into `activeLoanCount` + `preSaleLoanCount` + the paid-off and released counts on the detail `position` block.","nullable":true,"type":"number"},"loanType":{"nullable":true,"type":"string"},"loans":{"description":"The parcel's cached top-5 loans (may be fewer than `loanCount`; full history is on the loans index).","items":{"$ref":"#/components/schemas/PropertyLoan"},"type":"array"},"lotSquareFeet":{"nullable":true,"type":"number"},"mmPropertyId":{"nullable":true,"type":"string"},"mortgageBalance":{"nullable":true,"type":"number"},"ownerFirstName":{"nullable":true,"type":"string"},"ownerLastName":{"nullable":true,"type":"string"},"ownerName":{"nullable":true,"type":"string"},"partialBaths":{"nullable":true,"type":"number"},"preSaleLoanCount":{"description":"Mortgages excluded from `activeLoanCount` because the parcel sold after they were recorded — the seller's loan, assumed paid off at closing. Read this NEXT TO `activeLoanCount`, never alone: a non-zero value on a parcel that still has an active loan is the normal post-sale state and means the replacement mortgage was recorded. It is only a warning when `activeLoanCount` is `0`, which is what `activeLoanCountKnown` reports.","nullable":true,"type":"number"},"recordedInterestRate":{"description":"Genuine recorded note rate from the most-recent loan (sparse, ~7%). See `loans[]` for per-loan detail.","nullable":true,"type":"number"},"saleCount":{"nullable":true,"type":"number"},"salePropensity":{"$ref":"#/components/schemas/PropertySalePropensity"},"sales":{"$ref":"#/components/schemas/PropertySales"},"scoredAt":{"nullable":true,"type":"string"},"squareFeet":{"nullable":true,"type":"number"},"state":{"description":"Two-letter state abbreviation, uppercased (stored lowercase in OS)","nullable":true,"type":"string"},"stories":{"nullable":true,"type":"number"},"yearBuilt":{"nullable":true,"type":"number"},"zip":{"nullable":true,"type":"string"}},"required":["id"],"type":"object"},"PropertySummaryRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/PropertyAnalyticsFlatFilters"}},"type":"object"},"PropertyTractFloodZoneFilterValue":{"anyOf":[{"description":"One of (case-insensitive): A, AE, AH, AO, A99, V, VE","enum":["A","AE","AH","AO","A99","V","VE"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): A, AE, AH, AO, A99, V, VE","enum":["A","AE","AH","AO","A99","V","VE"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"PropertyTractIncomeLevelFilterValue":{"anyOf":[{"description":"One of (case-insensitive): low, moderate, middle, upper","enum":["low","moderate","middle","upper"],"type":"string"},{"description":"Match any of these values","items":{"description":"One of (case-insensitive): low, moderate, middle, upper","enum":["low","moderate","middle","upper"],"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"RealtimeConfigResponse":{"properties":{"app":{"description":"Topic app segment (e.g. `mm`)","type":"string"},"authorizerName":{"description":"IoT custom authorizer name used to build the WSS URL","type":"string"},"endpoint":{"description":"IoT realtime endpoint host","type":"string"},"stage":{"description":"Deployed stage segment (e.g. `prod`)","type":"string"},"userId":{"description":"The authenticated caller's user id (their MQTT topic key)","type":"string"}},"required":["endpoint","authorizerName","app","stage","userId"],"type":"object"},"RealtimeConfigUnavailable":{"properties":{"error":{"type":"string"}},"required":["error"],"type":"object"},"RelatedResponse":{"properties":{"data":{"description":"Ids of the linked records (unordered)","items":{"properties":{"id":{"description":"Id of the linked record, on the `to` entity","type":"string"}},"required":["id"],"type":"object"},"type":"array"},"from":{"description":"Type of the starting record","type":"string"},"linkQuality":{"description":"How the link was established. `primary` = the canonical identifier for this pair. `secondary` = a weaker but real alternate identifier, used only because the record carried nothing better. `null` = the record carries no linking identifier at all, so nothing was searched.","enum":["primary","secondary",null],"nullable":true,"type":"string"},"to":{"description":"Type of the linked records","type":"string"},"total":{"description":"Total linked records, before the `limit` page","type":"number"}},"required":["data","total","from","to","linkQuality"],"type":"object"},"ReplayRequest":{"properties":{"asOf":{"description":"The subscribe day (yyyy-MM-dd). Step 0 replays the backfill window a real subscribe would deliver on this date.","pattern":"^\\d{4}-\\d{2}-\\d{2}/u","type":"string"},"backfillDays":{"description":"Step-0 backfill lookback (days). Omit for the same 90-day window a real subscribe replays.","exclusiveMinimum":true,"minimum":0,"type":"integer"},"detectors":{"description":"Limit to specific triggers; all when omitted.","items":{"enum":["area_new_listing","watched_agent_pending","borrower_listed","epo_risk","agent_sale_closed","rate_term_refi_area","watched_sale","watched_property","watched_loan"],"type":"string"},"type":"array"},"steps":{"description":"Later dates (yyyy-MM-dd) to advance to. Each shows only what is NEW since the previous date — the forward delta the cron would have delivered. Sorted + de-duplicated; capped at 12 dates total.","items":{"pattern":"^\\d{4}-\\d{2}-\\d{2}/u","type":"string"},"type":"array"}},"required":["asOf"],"type":"object"},"ReplayResponse":{"properties":{"data":{"properties":{"capped":{"description":"True if the requested date list was truncated to the cap.","type":"boolean"},"steps":{"items":{"$ref":"#/components/schemas/ReplayStep"},"type":"array"}},"required":["steps","capped"],"type":"object"}},"required":["data"],"type":"object"},"ReplayStep":{"properties":{"counts":{"properties":{"matched":{"type":"integer"},"new":{"type":"integer"},"scanned":{"type":"integer"}},"required":["scanned","matched","new"],"type":"object"},"date":{"description":"The step's yyyy-MM-dd date.","type":"string"},"new":{"description":"Alerts new at this step (deduped against all prior steps).","items":{"$ref":"#/components/schemas/AlertDecision"},"type":"array"}},"required":["date","new","counts"],"type":"object"},"RunUserDetectorRequest":{"properties":{"backfillDays":{"description":"Ingest-axis lookback (days) the run replays past the global watermark. Omit to use the same 90-day window a real subscribe backfills, so the preview matches what the user receives on add.","exclusiveMinimum":true,"minimum":0,"type":"integer"},"detectors":{"description":"Limit to specific triggers; all six when omitted.","items":{"enum":["area_new_listing","watched_agent_pending","borrower_listed","epo_risk","agent_sale_closed","rate_term_refi_area","watched_sale","watched_property","watched_loan"],"type":"string"},"type":"array"},"dryRun":{"description":"Preview only (default true): compute what would fire without writing the feed, publishing events, or sending email. Set false to actually fire — persists a run record + delivers like the cron.","type":"boolean"}},"type":"object"},"RunUserDetectorResponse":{"properties":{"data":{"properties":{"correlationId":{"type":"string"},"dryRun":{"type":"boolean"},"perDetector":{"items":{"properties":{"decisions":{"description":"The alerts that fired for this detector (dry-run only).","items":{"$ref":"#/components/schemas/AlertDecision"},"type":"array"},"deduped":{"type":"integer"},"matched":{"type":"integer"},"published":{"type":"integer"},"scanned":{"type":"integer"},"type":{"enum":["area_new_listing","watched_agent_pending","borrower_listed","epo_risk","agent_sale_closed","rate_term_refi_area","watched_sale","watched_property","watched_loan"],"type":"string"},"written":{"type":"integer"}},"required":["type","scanned","matched","deduped","written","published"],"type":"object"},"type":"array"}},"required":["correlationId","dryRun","perDetector"],"type":"object"}},"required":["data"],"type":"object"},"SaleChartRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/SaleFlatFilters"},"measure":{"$ref":"#/components/schemas/ChartMeasure"},"period":{"$ref":"#/components/schemas/Period"},"slice":{"$ref":"#/components/schemas/SaleChartSlice"}},"required":["slice"],"type":"object"},"SaleChartSlice":{"enum":["city","county","state","zip"],"type":"string"},"SaleDetail":{"allOf":[{"$ref":"#/components/schemas/SaleSummary"},{"properties":{"buyerNames":{"nullable":true},"documentType":{"nullable":true,"type":"string"},"listAgent":{"nullable":true},"mlsBoards":{"nullable":true},"mlsListDate":{"nullable":true},"mlsPendingDate":{"nullable":true},"mlsSoldDate":{"nullable":true},"mmPropertyId":{"nullable":true,"type":"string"},"mmSaleId":{"nullable":true,"type":"string"},"sellerNames":{"nullable":true},"soldAgent":{"nullable":true}},"type":"object"}]},"SaleDetailResponse":{"properties":{"data":{"$ref":"#/components/schemas/SaleDetail"}},"required":["data"],"type":"object"},"SaleField":{"enum":["city","state","zipCode","county","salePrice","saleDate","listPrice","soldPrice","listingAgent","soldAgent","mlsStatus","beds","baths","sqft","yearBuilt","propertyType"],"type":"string"},"SaleFlatFilters":{"additionalProperties":false,"properties":{"baths":{"$ref":"#/components/schemas/NumericFilterValue"},"beds":{"$ref":"#/components/schemas/NumericFilterValue"},"city":{"$ref":"#/components/schemas/TextFilterValue"},"county":{"$ref":"#/components/schemas/TextFilterValue"},"fips":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"5-digit county FIPS code — the exact-code escape hatch for `county` (which also accepts a county name)."}]},"geoPoint":{"$ref":"#/components/schemas/GeoFilterValue"},"listPrice":{"$ref":"#/components/schemas/NumericFilterValue"},"listingAgent":{"$ref":"#/components/schemas/TextFilterValue"},"mlsStatus":{"$ref":"#/components/schemas/SaleMlsStatusFilterValue"},"mode":{"enum":["and","or"],"type":"string"},"propertyType":{"$ref":"#/components/schemas/TextFilterValue"},"saleDate":{"$ref":"#/components/schemas/DateFilterValue"},"salePrice":{"$ref":"#/components/schemas/NumericFilterValue"},"soldAgent":{"$ref":"#/components/schemas/TextFilterValue"},"soldPrice":{"$ref":"#/components/schemas/NumericFilterValue"},"sqft":{"$ref":"#/components/schemas/NumericFilterValue"},"state":{"$ref":"#/components/schemas/TextFilterValue"},"yearBuilt":{"$ref":"#/components/schemas/NumericFilterValue"},"zip":{"$ref":"#/components/schemas/TextFilterValue"},"zipCode":{"allOf":[{"$ref":"#/components/schemas/TextFilterValue"},{"description":"ZIP code. Canonical key on sales (matches loans `zipCode` and the response DTO); `zip` is an alias kept for cross-entity parity."}]}},"type":"object"},"SaleListRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/SaleFlatFilters"},"pagination":{"$ref":"#/components/schemas/Pagination"},"period":{"$ref":"#/components/schemas/Period"},"sort":{"items":{"properties":{"field":{"$ref":"#/components/schemas/SaleField"},"order":{"$ref":"#/components/schemas/SortOrder"}},"required":["field"],"type":"object"},"type":"array"}},"type":"object"},"SaleListResponse":{"properties":{"cursor":{"type":"string"},"data":{"items":{"$ref":"#/components/schemas/SaleSummary"},"type":"array"},"locationNormalizations":{"description":"How each location filter value resolved. Present when a `city`/`county`/`state`/`zip` filter was supplied.","items":{"$ref":"#/components/schemas/LocationNormalization"},"type":"array"},"total":{"type":"number"}},"required":["data","total"],"type":"object"},"SaleMlsStatusFilterValue":{"anyOf":[{"$ref":"#/components/schemas/MlsStatus"},{"description":"Match any MLS status","items":{"$ref":"#/components/schemas/MlsStatus"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"SaleSummary":{"properties":{"apn":{"nullable":true,"type":"string"},"baths":{"description":"Number of full bathrooms","nullable":true,"type":"number"},"beds":{"description":"Number of bedrooms","nullable":true,"type":"number"},"buyerName":{"nullable":true,"type":"string"},"city":{"nullable":true,"type":"string"},"coordinates":{"nullable":true,"properties":{"lat":{"type":"number"},"lon":{"type":"number"}},"required":["lat","lon"],"type":"object"},"daysOnMarket":{"nullable":true,"type":"number"},"fips":{"nullable":true,"type":"string"},"id":{"description":"Document ID","type":"string"},"listPrice":{"description":"MLS list price in dollars","nullable":true,"type":"number"},"listingAgentId":{"description":"ModelMatch agent ID for the listing agent","nullable":true,"type":"string"},"listingAgentName":{"nullable":true,"type":"string"},"mlsStatus":{"description":"MLS listing status code","enum":["SLD","ACT","PND","Cancelled","WDN","EXP","CNT","OFF","UNK","RNTD","RNT","LSE","RNT-SLD","RNT-ACT","RNT-PND","RNT-WDN","RNT-EXP","RNT-LSE","RNT-RNTD",null],"nullable":true,"type":"string"},"originalListPrice":{"description":"Original MLS list price in dollars","nullable":true,"type":"number"},"propertyType":{"description":"Listing property type (e.g. Residential, Condo)","nullable":true,"type":"string"},"recordingDate":{"nullable":true,"type":"string"},"salePrice":{"description":"Transaction price in dollars","nullable":true,"type":"number"},"sellerName":{"nullable":true,"type":"string"},"soldAgentId":{"description":"ModelMatch agent ID for the sold/buying agent","nullable":true,"type":"string"},"soldAgentName":{"nullable":true,"type":"string"},"soldPrice":{"description":"MLS sold price in dollars","nullable":true,"type":"number"},"sqft":{"description":"Living area in square feet","nullable":true,"type":"number"},"state":{"nullable":true,"type":"string"},"streetAddress":{"nullable":true,"type":"string"},"transactionDate":{"nullable":true,"type":"string"},"yearBuilt":{"description":"Year the property was built","nullable":true,"type":"number"},"zipCode":{"nullable":true,"type":"string"}},"required":["id"],"type":"object"},"SaleSummaryRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/SaleFlatFilters"},"period":{"$ref":"#/components/schemas/Period"}},"type":"object"},"SaleTimeSeriesRequest":{"additionalProperties":false,"properties":{"advancedFilters":{"$ref":"#/components/schemas/FilterNode"},"filters":{"$ref":"#/components/schemas/FilterNode"},"flatFilters":{"$ref":"#/components/schemas/SaleFlatFilters"},"interval":{"$ref":"#/components/schemas/Interval"},"measure":{"$ref":"#/components/schemas/Measure"},"period":{"$ref":"#/components/schemas/Period"},"segment":{"$ref":"#/components/schemas/SegmentDimension"}},"type":"object"},"SalesTimeSeriesBucket":{"properties":{"buyer":{"$ref":"#/components/schemas/SalesTimeSeriesSideMetrics"},"date":{"type":"string"},"dual":{"$ref":"#/components/schemas/SalesTimeSeriesSideMetrics"},"seller":{"$ref":"#/components/schemas/SalesTimeSeriesSideMetrics"},"total":{"$ref":"#/components/schemas/SalesTimeSeriesSideMetrics"}},"required":["date","total","buyer","seller","dual"],"type":"object"},"SalesTimeSeriesResponse":{"properties":{"current":{"items":{"$ref":"#/components/schemas/SalesTimeSeriesBucket"},"type":"array"},"measure":{"description":"Echo of the measure `measureValue` reports, so a caller never has to infer which metric it is plotting.","type":"string"},"previous":{"items":{"$ref":"#/components/schemas/SalesTimeSeriesBucket"},"nullable":true,"type":"array"}},"required":["measure","current","previous"],"type":"object"},"SalesTimeSeriesSideMetrics":{"properties":{"measureValue":{"description":"This side's value for the requested `measure` (`volume` when none was supplied). Null when this side has no in-bounds document for the measure's field — sentinel-filtered rows do not contribute, so an empty side reports null rather than 0.","nullable":true,"type":"number"},"units":{"type":"number"},"volume":{"type":"number"}},"required":["volume","units","measureValue"],"type":"object"},"ScoredBreakdownRequest":{"properties":{"period":{"$ref":"#/components/schemas/Period"},"sort":{"$ref":"#/components/schemas/BreakdownSort"}},"type":"object"},"SearchTokenResponse":{"properties":{"expiresAt":{"description":"ISO-8601 expiry","type":"string"},"host":{"description":"Search host to query directly","type":"string"},"indexes":{"description":"Index names the token may search","items":{"type":"string"},"type":"array"},"token":{"description":"Scoped search token","type":"string"}},"required":["token","host","indexes","expiresAt"],"type":"object"},"SearchTokenUnavailable":{"properties":{"error":{"type":"string"}},"required":["error"],"type":"object"},"SegmentDimension":{"enum":["side","transactionType"],"type":"string"},"SideMetrics":{"properties":{"avgListPrice":{"type":"number"},"avgSalePrice":{"type":"number"},"units":{"type":"number"},"volume":{"type":"number"}},"required":["volume","units","avgSalePrice","avgListPrice"],"type":"object"},"SidedSummaryResponse":{"properties":{"current":{"$ref":"#/components/schemas/SummaryPeriod"},"previous":{"allOf":[{"$ref":"#/components/schemas/SummaryPeriod"},{"nullable":true}]}},"required":["current","previous"],"type":"object"},"SidedTimeSeriesBucket":{"properties":{"buyer":{"properties":{"units":{"type":"number"},"volume":{"type":"number"}},"required":["volume","units"],"type":"object"},"date":{"type":"string"},"dual":{"properties":{"units":{"type":"number"},"volume":{"type":"number"}},"required":["volume","units"],"type":"object"},"seller":{"properties":{"units":{"type":"number"},"volume":{"type":"number"}},"required":["volume","units"],"type":"object"},"total":{"properties":{"units":{"type":"number"},"volume":{"type":"number"}},"required":["volume","units"],"type":"object"}},"required":["date","total","buyer","seller","dual"],"type":"object"},"SidedTimeSeriesResponse":{"properties":{"current":{"items":{"$ref":"#/components/schemas/SidedTimeSeriesBucket"},"type":"array"},"previous":{"items":{"$ref":"#/components/schemas/SidedTimeSeriesBucket"},"nullable":true,"type":"array"}},"required":["current","previous"],"type":"object"},"SimpleExcludedCounts":{"description":"Per-measure count of documents this query's sentinel guard excluded — documents that carry the measure's field but whose value is an out-of-range fill. Compare against `units` to see what share of the matched population each figure was computed over. Empty when the entity's measures are unguarded.","properties":{"avgListPrice":{"type":"number"},"avgPrice":{"type":"number"},"volume":{"type":"number"}},"type":"object"},"SimpleMetrics":{"properties":{"avgListPrice":{"description":"Average list price. Omitted entirely for entities with no list-price column — absence means 'not available here', not zero. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","type":"number"},"avgPrice":{"description":"Average sale price. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","type":"number"},"excluded":{"$ref":"#/components/schemas/SimpleExcludedCounts"},"units":{"description":"Number of transactions","type":"number"},"volume":{"description":"Total volume in dollars. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","type":"number"}},"required":["volume","units","avgPrice"],"type":"object"},"SimpleSummaryResponse":{"properties":{"current":{"$ref":"#/components/schemas/SimpleMetrics"},"previous":{"allOf":[{"$ref":"#/components/schemas/SimpleMetrics"},{"nullable":true}]}},"required":["current","previous"],"type":"object"},"SimpleTimeSeriesBucket":{"properties":{"date":{"type":"string"},"excluded":{"description":"How many of this bucket's documents the measure's sentinel guard excluded — documents that carry the field but whose value is an out-of-range fill. Additive and optional: absent when the measure is unguarded (a document count, or a field with no fill values). Present per BUCKET because exclusion is not uniform — one period or slice can be almost entirely fill values while its neighbors are clean, and a single response-level total would hide exactly that.","type":"number"},"measureValue":{"description":"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.","nullable":true,"type":"number"},"segments":{"items":{"$ref":"#/components/schemas/SimpleTimeSeriesSegment"},"type":"array"},"units":{"description":"Number of transactions","type":"number"},"volume":{"description":"This bucket's volume in dollars. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","type":"number"}},"required":["date","volume","units","measureValue"],"type":"object"},"SimpleTimeSeriesResponse":{"properties":{"current":{"items":{"$ref":"#/components/schemas/SimpleTimeSeriesBucket"},"type":"array"},"measure":{"description":"Echo of the measure `measureValue` reports, so a caller never has to infer which metric it is plotting.","type":"string"},"previous":{"items":{"$ref":"#/components/schemas/SimpleTimeSeriesBucket"},"nullable":true,"type":"array"}},"required":["measure","current","previous"],"type":"object"},"SimpleTimeSeriesSegment":{"properties":{"id":{"description":"Machine value behind `label` when the bucket key is an id rather than a name (today: the `lender` slice/segment, where `label` is the dictionary display name). Pass `id` — not `label` — back as a `lender` filter value. Absent on slices whose `label` is already the machine value.","type":"string"},"label":{"type":"string"},"measureValue":{"description":"This segment's value for the requested `measure`. Null when the segment has no in-bounds document for the measure's field.","nullable":true,"type":"number"},"units":{"description":"Number of transactions","type":"number"},"volume":{"description":"This segment's volume in dollars. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly.","type":"number"}},"required":["label","volume","units","measureValue"],"type":"object"},"SkipTraceAddress":{"additionalProperties":{"nullable":true},"nullable":true,"properties":{"addressValidity":{"nullable":true,"type":"string"},"city":{"nullable":true,"type":"string"},"county":{"nullable":true,"type":"string"},"formattedStreet":{"nullable":true,"type":"string"},"hash":{"nullable":true,"type":"string"},"houseNumber":{"nullable":true,"type":"string"},"state":{"nullable":true,"type":"string"},"street":{"nullable":true,"type":"string"},"streetNoUnit":{"nullable":true,"type":"string"},"zip":{"nullable":true,"type":"string"},"zipPlus4":{"nullable":true,"type":"string"}},"type":"object"},"SkipTraceEmail":{"properties":{"email":{"nullable":true,"type":"string"},"tested":{"anyOf":[{"type":"boolean"},{"type":"string"},{"nullable":true}]}},"type":"object"},"SkipTraceName":{"nullable":true,"properties":{"first":{"nullable":true,"type":"string"},"full":{"nullable":true,"type":"string"},"last":{"nullable":true,"type":"string"},"middle":{"nullable":true,"type":"string"}},"type":"object"},"SkipTracePerson":{"additionalProperties":{"nullable":true},"properties":{"death":{"additionalProperties":{"nullable":true},"nullable":true,"properties":{"deceased":{"nullable":true,"type":"boolean"}},"type":"object"},"dnc":{"additionalProperties":{"nullable":true},"nullable":true,"properties":{"tcpa":{"nullable":true,"type":"boolean"}},"type":"object"},"emails":{"items":{"$ref":"#/components/schemas/SkipTraceEmail"},"nullable":true,"type":"array"},"litigator":{"nullable":true,"type":"boolean"},"mailingAddress":{"$ref":"#/components/schemas/SkipTraceAddress"},"meta":{"additionalProperties":{"nullable":true},"nullable":true,"properties":{"error":{"anyOf":[{"type":"string"},{"type":"boolean"},{"nullable":true}]},"matched":{"nullable":true,"type":"boolean"}},"type":"object"},"name":{"$ref":"#/components/schemas/SkipTraceName"},"phoneNumbers":{"items":{"$ref":"#/components/schemas/SkipTracePhone"},"nullable":true,"type":"array"},"propertyAddress":{"$ref":"#/components/schemas/SkipTraceAddress"}},"type":"object"},"SkipTracePhone":{"properties":{"carrier":{"nullable":true,"type":"string"},"dnc":{"nullable":true,"type":"boolean"},"lastReportedDate":{"nullable":true,"type":"string"},"number":{"nullable":true,"type":"string"},"reachable":{"nullable":true,"type":"boolean"},"score":{"nullable":true,"type":"number"},"tested":{"anyOf":[{"type":"boolean"},{"type":"string"},{"nullable":true}]},"type":{"nullable":true,"type":"string"}},"type":"object"},"SortOrder":{"enum":["asc","desc"],"type":"string"},"StartAlertDetectorRequest":{"properties":{"detectors":{"items":{"enum":["area_new_listing","watched_agent_pending","borrower_listed","epo_risk","agent_sale_closed","rate_term_refi_area","watched_sale","watched_property","watched_loan"],"type":"string"},"type":"array"},"dryRun":{"type":"boolean"},"limitPerDetector":{"exclusiveMinimum":true,"minimum":0,"type":"integer"},"userIds":{"items":{"type":"string"},"type":"array"}},"type":"object"},"StartAlertDetectorResponse":{"properties":{"data":{"properties":{"arn":{"type":"string"},"started":{"type":"boolean"}},"required":["arn","started"],"type":"object"}},"required":["data"],"type":"object"},"StopAlertDetectorRequest":{"properties":{"taskArn":{"minLength":1,"type":"string"}},"required":["taskArn"],"type":"object"},"StopAlertDetectorResponse":{"properties":{"data":{"properties":{"arn":{"type":"string"},"stopped":{"type":"boolean"}},"required":["arn","stopped"],"type":"object"}},"required":["data"],"type":"object"},"SummaryPeriod":{"properties":{"buyer":{"$ref":"#/components/schemas/SideMetrics"},"buyerPct":{"type":"number"},"dual":{"$ref":"#/components/schemas/SideMetrics"},"dualPct":{"type":"number"},"seller":{"$ref":"#/components/schemas/SideMetrics"},"sellerPct":{"type":"number"},"total":{"$ref":"#/components/schemas/SideMetrics"}},"required":["total","buyer","seller","dual","buyerPct","sellerPct","dualPct"],"type":"object"},"TextFilterValue":{"anyOf":[{"type":"string"},{"description":"Match any value","items":{"type":"string"},"type":"array"},{"description":"Fuzzy text match","properties":{"match":{"type":"string"}},"required":["match"],"type":"object"},{"nullable":true}]},"UnreadCountResponse":{"properties":{"data":{"properties":{"count":{"type":"integer"}},"required":["count"],"type":"object"}},"required":["data"],"type":"object"},"UpdateAlertConditionsRequest":{"properties":{"conditions":{"$ref":"#/components/schemas/AlertConditions"},"email":{"description":"Contact email stored for the alert digest.","type":"string"},"emailEnabled":{"description":"Per-trigger email opt-ins to change (others keep their value). Off by default — turn one on to also receive an email when it fires.","properties":{"agent_sale_closed":{"type":"boolean"},"area_new_listing":{"type":"boolean"},"borrower_listed":{"type":"boolean"},"epo_risk":{"type":"boolean"},"rate_term_refi_area":{"type":"boolean"},"watched_agent_pending":{"type":"boolean"},"watched_loan":{"type":"boolean"},"watched_property":{"type":"boolean"},"watched_sale":{"type":"boolean"}},"type":"object"},"enabled":{"description":"Per-trigger on/off flags to change (others keep their value).","properties":{"agent_sale_closed":{"type":"boolean"},"area_new_listing":{"type":"boolean"},"borrower_listed":{"type":"boolean"},"epo_risk":{"type":"boolean"},"rate_term_refi_area":{"type":"boolean"},"watched_agent_pending":{"type":"boolean"},"watched_loan":{"type":"boolean"},"watched_property":{"type":"boolean"},"watched_sale":{"type":"boolean"}},"type":"object"},"name":{"description":"Display name.","type":"string"},"nmlsId":{"description":"The loan officer's NMLS id. Required to enable the borrower-centric triggers (borrower_listed, epo_risk); the agent + area triggers work without it.","type":"string"}},"type":"object"},"WatchedAgent":{"properties":{"addedAt":{"type":"string"},"agentId":{"description":"Agent id.","type":"string"},"name":{"type":"string"},"source":{"description":"How the agent entered the watchlist — added by hand or auto-derived from recent buyer-side deals.","enum":["manual","auto_buyer_24mo"],"type":"string"}},"required":["agentId","source","addedAt"],"type":"object"},"WatchedAgentsResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/WatchedAgent"},"type":"array"}},"required":["data"],"type":"object"},"WatchedArea":{"properties":{"addedAt":{"type":"string"},"id":{"description":"Opaque id used to remove the area.","type":"string"},"lat":{"description":"Radius center latitude.","type":"number"},"lon":{"description":"Radius center longitude.","type":"number"},"maxLat":{"description":"Box north edge.","type":"number"},"maxLon":{"description":"Box east edge.","type":"number"},"minLat":{"description":"Box south edge.","type":"number"},"minLon":{"description":"Box west edge.","type":"number"},"radiusMeters":{"description":"Radius in meters (canonical unit).","type":"number"},"state":{"description":"2-letter state ('' for zip + geo areas).","type":"string"},"type":{"enum":["city","county","zip","bbox","radius"],"type":"string"},"value":{"type":"string"}},"required":["id","type","value","state","addedAt"],"type":"object"},"WatchedAreasResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/WatchedArea"},"type":"array"}},"required":["data"],"type":"object"},"WatchedDocument":{"properties":{"addedAt":{"type":"string"},"documentId":{"type":"string"},"documentType":{"enum":["sale","property","loan"],"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/WatchedDocumentRule"},"type":"array"}},"required":["documentType","documentId","rules","addedAt"],"type":"object"},"WatchedDocumentPredicate":{"properties":{"field":{"description":"Catalog field alias.","type":"string"},"id":{"description":"Stable predicate id.","type":"string"},"op":{"enum":["gt","gte","lt","lte","eq","between","pct_change_gte","abs_change_gte","changed","changed_to"],"type":"string"},"stringValue":{"type":"string"},"value":{"type":"number"},"value2":{"type":"number"}},"required":["id","field","op"],"type":"object"},"WatchedDocumentRule":{"properties":{"id":{"description":"Stable rule id.","type":"string"},"match":{"enum":["all","any"],"type":"string"},"predicates":{"items":{"$ref":"#/components/schemas/WatchedDocumentPredicate"},"type":"array"}},"required":["id","match","predicates"],"type":"object"},"WatchedDocumentsResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/WatchedDocument"},"type":"array"}},"required":["data"],"type":"object"}},"securitySchemes":{"apiKeyAuth":{"in":"header","name":"x-api-key","type":"apiKey"},"bearerAuth":{"bearerFormat":"JWT","scheme":"bearer","type":"http"}}},"info":{"description":"ModelMatch API — mortgage and real-estate market data.\n\n## Bulk delivery limits\n\nThe `POST /{entity}/bulk-delivery` endpoints export a full result set to\nS3 as NDJSON, JSON, CSV, or Parquet.\n\n- **Up to 1,000 rows per delivery: no entitlement required.** Available to\n  every authenticated caller.\n- **Above 1,000 rows: requires the entity's `bulk-delivery.{entity}`\n  entitlement** (e.g. `bulk-delivery.loans`). The grant's scope sets your\n  row ceiling and may also restrict which rows and fields you receive.\n\nA delivery that would exceed the limit available to you is rejected with\n`403 entitlement_missing`, reporting the matched row count and the ceiling\nthat applied. To stay under the limit, pass `limit` — the job then delivers\n(and bills for) only the first `limit` rows of a broader query.\n\n**Need a higher limit?** Email support@modelmatch.com to request the\nentitlement. Limits are raised per organization and per entity.\n\nBulk delivery is billed at 1 credit per 100 delivered rows whether or not\nan entitlement is held.","title":"ModelMatch API","version":"3.45.5"},"openapi":"3.1.0","paths":{"/agents":{"post":{"description":"Search and list individual real-estate agents with filters — one row per agent. Filter by name, location (state, city, zip), brokerage/office, and production metrics (sales volume, transaction units, price range), with sorting and cursor pagination. LOCATION SEMANTICS: the state/city/zip filters match ANY of an agent's location signals — their listed city/state, their office address(es), AND the markets where they actually closed transactions (production) — combined with OR. So an agent matches a searched location if their office OR their production is there. A search for city \"Long Beach\" can therefore return agents whose office or displayed primary market is in a different city/state, because they transacted in Long Beach. The `state`/`city` returned on each row reflect the agent's primary market and may differ from the searched location. (Use the `office` filter to match by brokerage/office name, and the per-agent city/county/state breakdown endpoints to rank an agent's volume within a specific market.) RANKING BY DEAL SIDE: combine a location filter with `sort` on `buyerVolume`/`buyerUnits` (or `sellerVolume`/`sellerUnits`, `dualVolume`/`dualUnits`) to rank agents by how active they are representing buyers vs. sellers in that market — e.g. sort `buyerVolume` descending for the most active buyer-side agents in a state or city. This is the per-agent record search: use it to find specific real-estate agents or build a filtered agent list. (For a single agent by ID use the agent detail endpoint.) If you only need how many agents match and not the records themselves, send the same request body to `countAgents`.","operationId":"listAgents","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentListResponse"}}},"description":"Paginated list of agents"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error. Includes unresolvable location filters: a `city`/`county`/`state`/`zip` value that does not match a recognized location returns 400 rather than an empty result set. Resolve the name with `instantSearch` (use an id from its `results.locations[]`) or `suggestLocations` (use the `id` of a `source: \"dictionary\"` result), then pass that id back as the filter value."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Location dictionary temporarily unavailable. Only returned for a NEGATED location filter (`neq`, or `not`), which cannot be honoured without resolving the excluded value — answering anyway would return the records you asked to exclude. Positive location filters are unaffected. Retry shortly; the filter value itself was not rejected."}},"summary":"Search agents with filters","tags":["Agents"]}},"/agents/analytics/chart":{"post":{"operationId":"agentAnalyticsChart","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentChartRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChartResponse"}}},"description":"Chart data"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Configurable chart (measure × slice) over the agent's sales","tags":["Agents"]}},"/agents/analytics/summary":{"post":{"operationId":"agentAnalyticsSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSummaryRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SidedSummaryResponse"}}},"description":"Sided summary with previous-period comparison"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Production summary with buyer/seller/dual split + previous period","tags":["Agents"]}},"/agents/analytics/time-series":{"post":{"operationId":"agentAnalyticsTimeSeries","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentTimeSeriesRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SidedTimeSeriesResponse"}}},"description":"Time-series with side splits + previous period"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Agent volume/units over time with buyer/seller/dual split","tags":["Agents"]}},"/agents/bulk-delivery":{"post":{"description":"Queues an ECS task that dumps every matching agents document to S3 in the requested format. Returns 202 with a jobId; poll `GET /v1/agents/bulk-delivery/{jobId}` for status + the signed download URL.\n\n**Row limit.** Deliveries of up to 1,000 rows need no entitlement. Above that, the org's `bulk-delivery.agents` entitlement is required and its scope (row ceiling, row filters, allowed fields) governs the delivery; without it the request is rejected with 403 `entitlement_missing`. Pass `limit` at or below the ceiling to deliver a capped subset of a broader query. Email support@modelmatch.com to request a limit increase.\n\nDelivery is billed at 1 credit per 100 rows regardless of entitlement.","operationId":"submitAgentsBulkDelivery","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/AgentListRequest"},{"additionalProperties":false,"properties":{"fields":{"description":"Optional output column projection, named by the response DTO fields (the same camelCase fields the list endpoint returns, e.g. `city`, `interestRate`). Intersected with the entitlement scope's allowedFields and the entity's full column set. If empty after intersection, falls back to all columns. It also SELECTS the opt-in columns, which are not part of the list DTO and are never delivered unless named here: `communityLending` (properties, originators, companies, branches) — the Community Lending neighborhood profile, identical to the block on the entity's detail endpoint; `parties` (properties) — the mortgage parties attributed to the parcel, by attribution scope; and `marketCount` / `countyCount` / `stateCount` / `zipCount` / `lenderCount` (originators) — the market-breadth rollups you can already filter on. In `csv` and `parquet` the two block columns are JSON-encoded cells; in `json` and `ndjson` they are nested objects.","items":{"minLength":1,"type":"string"},"type":"array"},"format":{"$ref":"#/components/schemas/BulkDeliveryFormat"},"limit":{"description":"Optional hard cap on the number of rows delivered — and therefore billed (1 credit / 100 rows). The job delivers the first `limit` rows in sort order (default newest-first) and bills only for those. If the query matches fewer than `limit`, all matches are delivered. Distinct from the page-size `size` field, which is ignored on this endpoint. The row ceiling still applies — 1,000 without the entity's bulk-delivery entitlement, or the entitlement's `maxRows` with it. A `limit` above the ceiling is rejected, but a `limit` at or below it lets you export a capped top-N even when the full match exceeds the ceiling — which is the intended way to run a broad query under the 1,000-row allowance.","example":1000,"exclusiveMinimum":true,"minimum":0,"type":"integer"}},"required":["format"],"type":"object"}]}}}},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliverySubmitResponse"}}},"description":"Job queued; ECS task launched"},"400":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/BulkDeliveryPreflightExceeded"}]}}},"description":"Validation failure OR delivery would exceed the entitlement's maxRows"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryInsufficientCredits"}}},"description":"Insufficient credits (balance < estimatedTotal / 100)"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryForbidden"}}},"description":"Delivery exceeds the 1,000-row limit available without the `bulk-delivery.agents` entitlement. Lower `limit`, narrow the filters, or contact support for a limit increase."},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Preflight / S3 / DDB / ECS launch failure"}},"summary":"Submit a bulk-delivery job for agents","tags":["Agents"]}},"/agents/bulk-delivery/{jobId}":{"get":{"operationId":"getAgentsBulkDeliveryJob","parameters":[{"description":"Job ID returned by `POST /v1/agents/bulk-delivery`","in":"path","name":"jobId","required":true,"schema":{"description":"Job ID returned by `POST /v1/agents/bulk-delivery`","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryStatusResponse"}}},"description":"Job status (resultsUrl re-signed if completed)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Caller does not own this job"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Job not found (or expired past 30d TTL)"}},"summary":"Get bulk-delivery job status for agents","tags":["Agents"]}},"/agents/count":{"post":{"description":"Return the exact number of agents matching the given filters. Accepts the same request body as `listAgents` (pagination and sort are ignored). Use this when you only need a total; to get the matching agents themselves, send the same request body to `listAgents`.","operationId":"countAgents","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountResponse"}}},"description":"Exact count of matching agents"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Location dictionary temporarily unavailable. Only returned for a NEGATED location filter (`neq`, or `not`), which cannot be honoured without resolving the excluded value — answering anyway would return the records you asked to exclude. Positive location filters are unaffected. Retry shortly; the filter value itself was not rejected."}},"summary":"Count agents matching filters","tags":["Agents"],"x-mm-records-via":"listAgents"}},"/agents/{id}":{"get":{"operationId":"getAgent","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}},{"description":"Period for volume/units (default: last12Months)","in":"query","name":"period","required":false,"schema":{"allOf":[{"$ref":"#/components/schemas/Period"},{"description":"Period for volume/units (default: last12Months)"}]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentDetailResponse"}}},"description":"Agent detail"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Agent not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large"}},"summary":"Get agent by ID","tags":["Agents"]}},"/agents/{id}/breakdowns/cities":{"post":{"operationId":"agentCities","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the agent's sales by cities"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"City volume breakdown across the agent's sales","tags":["Agents"]}},"/agents/{id}/breakdowns/companies":{"post":{"operationId":"agentCompanies","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoredBreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Pre-aggregated companies breakdown from the agent's scored doc"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Mortgage companies the agent dealt with (pre-aggregated)","tags":["Agents"]}},"/agents/{id}/breakdowns/counties":{"post":{"operationId":"agentCounties","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the agent's sales by counties"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"County (FIPS) volume breakdown","tags":["Agents"]}},"/agents/{id}/breakdowns/lenders":{"post":{"operationId":"agentLenders","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoredBreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Pre-aggregated lenders breakdown from the agent's scored doc"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Raw-name lenders encountered (pre-aggregated)","tags":["Agents"]}},"/agents/{id}/breakdowns/offices":{"post":{"operationId":"agentOffices","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the agent's sales by offices"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Listing offices the agent has closed through","tags":["Agents"]}},"/agents/{id}/breakdowns/originators":{"post":{"operationId":"agentOriginators","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoredBreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Pre-aggregated originators breakdown from the agent's scored doc"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Loan officers the agent worked with (pre-aggregated)","tags":["Agents"]}},"/agents/{id}/breakdowns/states":{"post":{"operationId":"agentStates","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the agent's sales by states"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"State volume breakdown","tags":["Agents"]}},"/agents/{id}/breakdowns/zip-codes":{"post":{"operationId":"agentZipCodes","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the agent's sales by zip-codes"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Zip-code volume breakdown","tags":["Agents"]}},"/agents/{id}/markets":{"post":{"description":"Rank the ZIP markets one real-estate agent works, with volume, transaction counts and mean sale price per market, plus a weighted summary across the whole footprint. Optionally narrow to a ZIP list or a date window. REACH, NOT MARKET SHARE: an agent belongs to every market they touch — where their office is AND everywhere they have transacted — so one agent is counted in several markets at once. Per-market agent counts therefore over-sum: they cannot be added together, and dividing one into a total does not produce a market share. The only percentage returned, `shareOfScope`, is each market's share of this agent's volume across the scope requested and sums to 100 over that scope; there is no share-of-whole-book figure, because the transaction records carry no per-agent total to divide by. TWO COUNTS, ON PURPOSE: `transactions` counts transaction records; `units` counts the ones carrying a price, which are the records behind `volume` and `avgSalePrice`. Roughly half of an agent's records are priced, so dividing volume by `transactions` understates the average by about 2×. Figures are computed live from the agent's transaction records — an agent record carries no stored market rollup — and are ranked across their busiest ZIP markets. When a ZIP scope returns no markets, `reach.presentInScope` distinguishes 'works there, nothing closed in the window' from 'not present at all'. The summary also carries a Community Lending mix: what kind of neighborhood these markets are, weighted by the agent's activity in each. These are U.S. Census tract-level aggregates describing whole neighborhoods — never an individual, household or client attribute — and on this surface the basis is always the markets in scope, since an agent record carries no stored neighborhood rollup.","operationId":"agentMarkets","parameters":[{"description":"Agent ID","in":"path","name":"id","required":true,"schema":{"description":"Agent ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentMarketsRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentMarketsResponse"}}},"description":"The agent's blended market footprint"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"The ZIP markets this agent works, blended","tags":["Agents"]}},"/agents/{id}/properties":{"post":{"operationId":"agentProperties","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRelationRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentPropertiesResponse"}}},"description":"Paginated list of properties for this agent"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Properties this agent has transacted on","tags":["Agents"]}},"/agents/{id}/sales":{"post":{"operationId":"agentSales","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRelationRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSalesResponse"}}},"description":"Paginated list of sales for this agent"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Sales transactions where this agent was listing or selling side","tags":["Agents"]}},"/originators":{"post":{"description":"Search and list individual loan originators (LOs — NMLS-registered mortgage loan officers) with filters — one row per originator. Filter by name, NMLS ID, location (state, city), employer/company, and production metrics (loan volume, units, product mix), with sorting and cursor pagination. LOCATION SEMANTICS: the state/city filters match an originator's PRODUCTION GEOGRAPHY — the markets where they actually originated loans in the selected period — not where their office or employer sits. An LO who lends across several markets matches a filter for ANY of those markets, while the `state`/`city` returned on each row reflect only their PRIMARY (highest-volume) market. So a search for city \"Long Beach\" can return an LO whose displayed location is a different city/state (e.g. their top market is in Arizona) — they still originated loans in Long Beach, it just isn't their #1 market. To rank originators by their volume within a specific market, sort by volume after filtering, or use the per-originator city/county/state breakdown endpoints. This is the per-originator record search: use it to find specific loan officers or build a filtered LO list. (For a single originator by NMLS ID use the originator detail endpoint.) If you only need how many originators match and not the records themselves, send the same request body to `countOriginators`.","operationId":"listOriginators","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorListResponse"}}},"description":"Paginated list of originators"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error. Includes unresolvable location filters: a `city`/`county`/`state`/`zip` value that does not match a recognized location returns 400 rather than an empty result set. Resolve the name with `instantSearch` (use an id from its `results.locations[]`) or `suggestLocations` (use the `id` of a `source: \"dictionary\"` result), then pass that id back as the filter value."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Search originators with filters","tags":["Originators"]}},"/originators/analytics/chart":{"post":{"operationId":"originatorAnalyticsChart","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorChartRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChartResponse"}}},"description":"Chart data. Money measures (`volume`, `avgSalePrice`, `avgListPrice`) are sentinel-guarded. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Configurable chart (measure × slice) over one LO's loans","tags":["Originators"]}},"/originators/analytics/summary":{"post":{"operationId":"originatorAnalyticsSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorSummaryRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleSummaryResponse"}}},"description":"Current + previous-period summary"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Production summary with previous-period comparison","tags":["Originators"]}},"/originators/analytics/time-series":{"post":{"operationId":"originatorAnalyticsTimeSeries","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorTimeSeriesRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleTimeSeriesResponse"}}},"description":"Time-series with previous-period comparison"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Originator volume / units over time","tags":["Originators"]}},"/originators/bulk-delivery":{"post":{"description":"Queues an ECS task that dumps every matching originators document to S3 in the requested format. Returns 202 with a jobId; poll `GET /v1/originators/bulk-delivery/{jobId}` for status + the signed download URL.\n\n**Row limit.** Deliveries of up to 1,000 rows need no entitlement. Above that, the org's `bulk-delivery.originators` entitlement is required and its scope (row ceiling, row filters, allowed fields) governs the delivery; without it the request is rejected with 403 `entitlement_missing`. Pass `limit` at or below the ceiling to deliver a capped subset of a broader query. Email support@modelmatch.com to request a limit increase.\n\nDelivery is billed at 1 credit per 100 rows regardless of entitlement.","operationId":"submitOriginatorsBulkDelivery","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/OriginatorListRequest"},{"additionalProperties":false,"properties":{"fields":{"description":"Optional output column projection, named by the response DTO fields (the same camelCase fields the list endpoint returns, e.g. `city`, `interestRate`). Intersected with the entitlement scope's allowedFields and the entity's full column set. If empty after intersection, falls back to all columns. It also SELECTS the opt-in columns, which are not part of the list DTO and are never delivered unless named here: `communityLending` (properties, originators, companies, branches) — the Community Lending neighborhood profile, identical to the block on the entity's detail endpoint; `parties` (properties) — the mortgage parties attributed to the parcel, by attribution scope; and `marketCount` / `countyCount` / `stateCount` / `zipCount` / `lenderCount` (originators) — the market-breadth rollups you can already filter on. In `csv` and `parquet` the two block columns are JSON-encoded cells; in `json` and `ndjson` they are nested objects.","items":{"minLength":1,"type":"string"},"type":"array"},"format":{"$ref":"#/components/schemas/BulkDeliveryFormat"},"limit":{"description":"Optional hard cap on the number of rows delivered — and therefore billed (1 credit / 100 rows). The job delivers the first `limit` rows in sort order (default newest-first) and bills only for those. If the query matches fewer than `limit`, all matches are delivered. Distinct from the page-size `size` field, which is ignored on this endpoint. The row ceiling still applies — 1,000 without the entity's bulk-delivery entitlement, or the entitlement's `maxRows` with it. A `limit` above the ceiling is rejected, but a `limit` at or below it lets you export a capped top-N even when the full match exceeds the ceiling — which is the intended way to run a broad query under the 1,000-row allowance.","example":1000,"exclusiveMinimum":true,"minimum":0,"type":"integer"}},"required":["format"],"type":"object"}]}}}},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliverySubmitResponse"}}},"description":"Job queued; ECS task launched"},"400":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/BulkDeliveryPreflightExceeded"}]}}},"description":"Validation failure OR delivery would exceed the entitlement's maxRows"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryInsufficientCredits"}}},"description":"Insufficient credits (balance < estimatedTotal / 100)"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryForbidden"}}},"description":"Delivery exceeds the 1,000-row limit available without the `bulk-delivery.originators` entitlement. Lower `limit`, narrow the filters, or contact support for a limit increase."},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Preflight / S3 / DDB / ECS launch failure"}},"summary":"Submit a bulk-delivery job for originators","tags":["Originators"]}},"/originators/bulk-delivery/{jobId}":{"get":{"operationId":"getOriginatorsBulkDeliveryJob","parameters":[{"description":"Job ID returned by `POST /v1/originators/bulk-delivery`","in":"path","name":"jobId","required":true,"schema":{"description":"Job ID returned by `POST /v1/originators/bulk-delivery`","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryStatusResponse"}}},"description":"Job status (resultsUrl re-signed if completed)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Caller does not own this job"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Job not found (or expired past 30d TTL)"}},"summary":"Get bulk-delivery job status for originators","tags":["Originators"]}},"/originators/count":{"post":{"description":"Return the exact number of originators matching the given filters. Accepts the same request body as `listOriginators` (pagination and sort are ignored). Use this when you only need a total; to get the matching originators themselves, send the same request body to `listOriginators`.","operationId":"countOriginators","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountResponse"}}},"description":"Exact count of matching originators"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Count originators matching filters","tags":["Originators"],"x-mm-records-via":"listOriginators"}},"/originators/{nmlsId}":{"get":{"operationId":"getOriginator","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}},{"description":"Period for volume/units (default: last12Months)","in":"query","name":"period","required":false,"schema":{"allOf":[{"$ref":"#/components/schemas/Period"},{"description":"Period for volume/units (default: last12Months)"}]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorDetailResponse"}}},"description":"Originator detail"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Originator not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large"}},"summary":"Get originator by NMLS ID","tags":["Originators"]}},"/originators/{nmlsId}/breakdowns/agents":{"post":{"description":"Ranks the real-estate agents on the selling side of this LO's loans, by volume. Buckets whose name is an MLS placeholder for \"no selling agent recorded\" (`non member`, `non listed agent`, and ~140 board-specific spellings) are excluded rather than ranked as agents — they are not people and cannot be resolved with `GET /v1/agents/{id}`. Percentages are shares of the LO's whole loan population, so they do not sum to 100 across the page.","operationId":"originatorAgents","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by agents"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Real-estate agents this LO co-closed with","tags":["Originators"]}},"/originators/{nmlsId}/breakdowns/branches":{"post":{"operationId":"originatorBranches","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by branches"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Branch (broker) history for this LO","tags":["Originators"]}},"/originators/{nmlsId}/breakdowns/brokers":{"post":{"operationId":"originatorBrokers","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by brokers"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Broker shops this LO originated loans through (name-resolved)","tags":["Originators"]}},"/originators/{nmlsId}/breakdowns/cities":{"post":{"operationId":"originatorCitiesBreakdown","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by cities"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"City volume breakdown across this LO's loans","tags":["Originators"]}},"/originators/{nmlsId}/breakdowns/companies":{"post":{"operationId":"originatorCompanies","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by companies"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Funding companies (employer history) for this LO","tags":["Originators"]}},"/originators/{nmlsId}/breakdowns/counties":{"post":{"operationId":"originatorCountiesBreakdown","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by counties"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"County (FIPS) volume breakdown across this LO's loans","tags":["Originators"]}},"/originators/{nmlsId}/breakdowns/lenders":{"post":{"operationId":"originatorLenders","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by lenders"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Lenders this LO has originated through","tags":["Originators"]}},"/originators/{nmlsId}/breakdowns/offices":{"post":{"operationId":"originatorOffices","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by broker (office)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Real-estate offices this LO closed through (with sponsoring company)","tags":["Originators"]}},"/originators/{nmlsId}/breakdowns/states":{"post":{"operationId":"originatorStatesBreakdown","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by states"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"State volume breakdown across this LO's loans","tags":["Originators"]}},"/originators/{nmlsId}/breakdowns/zip-codes":{"post":{"operationId":"originatorZipCodes","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by zip-codes"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Zip-code volume breakdown","tags":["Originators"]}},"/originators/{nmlsId}/loans":{"post":{"operationId":"originatorLoans","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanListResponse"}}},"description":"Paginated list of loans originated by this LO"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Loans originated by this LO","tags":["Originators"]}},"/originators/{nmlsId}/markets":{"post":{"description":"One blended view of a loan officer's lending footprint: the ZIP codes they originated in, city / county / state rollups of the same scope, and the period totals those markets are a share of. AVERAGES ARE VOLUME-WEIGHTED: the summary loan size is Σ volume ÷ Σ units, not an unweighted mean of the per-market averages (on a real footprint the two differ by thousands of dollars). Sending `zipCodes` narrows every grain to those ZIPs; sending a `dateRange` re-cuts the window. Either switches the response from the LO's pre-aggregated footprint to a live aggregation of their loans — `source` and `sourceReasons` say which was used, and bucket `key` forms differ between them (use `name` for display). All shares on this response are 0–100 percentages. A summary can cover less than the whole book: production that could not be attributed to a place is held out and reported in `summary.unresolved` rather than being folded in or silently dropped. The summary also carries a Community Lending mix — what kind of neighborhood this book lands in. These are U.S. Census tract-level aggregates describing whole neighborhoods, never individual, household or applicant attributes. Unscoped it is the LO's own whole-period mix; a ZIP or date scope recomputes it over the markets in scope, and `summary.communityLending.basis` says which you got.","operationId":"originatorMarkets","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorMarketsRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorMarketsResponse"}}},"description":"The LO's blended market footprint"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Originator not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"The markets this LO lends in","tags":["Originators"]}},"/originators/{nmlsId}/properties":{"post":{"description":"Returns the parcels this loan officer is attributed to in public record — the reverse of the `parties` block on `GET /v1/properties/{id}`. Accepts the same filters, sorts and pagination as the main property search, so a caller can ask 'this LO's parcels in Travis County built after 2015' in one request. Attribution is ALL-TIME: a parcel stays in this LO's set after the loan is paid off, because the question is career reach rather than current book. An LO with no attributed parcels returns an empty page, not a 404 — the LO may be real and simply have nothing in the public record yet.","operationId":"originatorProperties","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyListResponse"}}},"description":"Paginated list of parcels attributed to this LO"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Properties this loan officer has touched","tags":["Originators"]}},"/v1/admin/alerts/runs":{"get":{"description":"Run history, newest first. One record per non-dry-run.","operationId":"adminListAlertRuns","parameters":[{"description":"Max items to return (default 25).","in":"query","name":"limit","required":false,"schema":{"description":"Max items to return (default 25).","maximum":100,"minimum":1,"type":"integer"}},{"description":"Pagination cursor from a previous response.","in":"query","name":"cursor","required":false,"schema":{"description":"Pagination cursor from a previous response.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAlertRunsResponse"}}},"description":"Paginated run history"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"List detector runs (admin)","tags":["Admin"]}},"/v1/admin/alerts/runs/{id}":{"get":{"operationId":"adminGetAlertRun","parameters":[{"description":"Opaque run id (from the run list).","in":"path","name":"id","required":true,"schema":{"description":"Opaque run id (from the run list).","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAlertRunResponse"}}},"description":"The run record"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Run not found"}},"summary":"Get one detector run (admin)","tags":["Admin"]}},"/v1/admin/alerts/task/start":{"post":{"operationId":"adminStartAlertDetector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartAlertDetectorRequest"}}},"required":false},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartAlertDetectorResponse"}}},"description":"The launched task arn"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Start an on-demand detector run (admin)","tags":["Admin"]}},"/v1/admin/alerts/task/status":{"get":{"operationId":"adminGetAlertDetectorStatus","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertDetectorStatusResponse"}}},"description":"Running flag + any running tasks"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Is the detector running right now? (admin)","tags":["Admin"]}},"/v1/admin/alerts/task/stop":{"post":{"operationId":"adminStopAlertDetector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StopAlertDetectorRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StopAlertDetectorResponse"}}},"description":"The stopped task arn"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Stop a running detector task (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/conditions":{"get":{"operationId":"adminGetUserAlertConditions","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAlertConditionsResponse"}}},"description":"The user's settings + identity (defaults if none saved)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Get a user's alert settings (admin)","tags":["Admin"]},"put":{"operationId":"adminUpdateUserAlertConditions","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUpdateAlertConditionsRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAlertConditionsResponse"}}},"description":"The saved settings"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"An NMLS id is required to enable the borrower-centric triggers"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Set a user's alert settings on their behalf (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/digests":{"get":{"operationId":"adminListUserAlertDigests","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}},{"description":"Max items to return (default 25).","in":"query","name":"limit","required":false,"schema":{"description":"Max items to return (default 25).","maximum":100,"minimum":1,"type":"integer"}},{"description":"Pagination cursor from a previous response.","in":"query","name":"cursor","required":false,"schema":{"description":"Pagination cursor from a previous response.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAlertDigestResponse"}}},"description":"Paginated digest feed (newest first)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"List a user's alert digests (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/history/clear":{"post":{"description":"Deletes the user's fire-once dedupe markers + their feed (LOG) rows (and digest rows) so the detector can re-fire the same alerts — a debug aid for testing the pipeline end-to-end. Optionally scope to specific alert types; a full clear also resets the unread counter. Leaves the user's alert settings and watchlists untouched.","operationId":"adminClearUserAlertHistory","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClearAlertHistoryRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClearAlertHistoryResponse"}}},"description":"Counts of deleted dedupe / log / digest rows"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Clear a user's fired-alert history (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/log":{"get":{"operationId":"adminListUserAlertLog","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}},{"description":"Max items to return (default 25).","in":"query","name":"limit","required":false,"schema":{"description":"Max items to return (default 25).","maximum":100,"minimum":1,"type":"integer"}},{"description":"Pagination cursor from a previous response.","in":"query","name":"cursor","required":false,"schema":{"description":"Pagination cursor from a previous response.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAlertLogResponse"}}},"description":"Paginated feed (newest first)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"List a user's alert feed (admin)","tags":["Admin"]},"post":{"operationId":"adminPushUserAlert","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPushAlertRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPushAlertResponse"}}},"description":"Whether it was written (false = deduped)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Push a one-off alert into a user's feed (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/log/mark-all-read":{"post":{"operationId":"adminMarkAllUserAlertsRead","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertsOkResponse"}}},"description":"Unread count reset to 0"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Clear a user's unread badge (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/log/{id}":{"get":{"description":"The raw DynamoDB document for one alert — the drill-in behind a global alert row. 404 when it was never written (e.g. a deduped / dry-run decision) or the id is malformed.","operationId":"adminGetUserAlertLogItem","parameters":[{"in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Alert id (from the feed).","in":"path","name":"id","required":true,"schema":{"description":"Alert id (from the feed).","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAlertRawResponse"}}},"description":"The raw stored alert item"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"No stored alert for that id"}},"summary":"Get the raw stored item for one alert (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/log/{id}/read":{"post":{"operationId":"adminMarkUserAlertRead","parameters":[{"in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Alert id (from the feed).","in":"path","name":"id","required":true,"schema":{"description":"Alert id (from the feed).","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertsOkResponse"}}},"description":"Marked read (idempotent)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Mark one of a user's alerts read (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/replay":{"post":{"description":"Backtest: run the detector as-of `asOf` (the subscribe day) and each later `step` date, returning a timeline of what's NEW at each step. Always a dry-run — writes nothing, sends no email. A reconstruction from the current index filtered to each date, not a perfect snapshot.","operationId":"adminReplayUserAlerts","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplayRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplayResponse"}}},"description":"Per-step timeline of newly-firing alerts"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Replay a user's alerts over time (admin, dry-run)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/run":{"post":{"description":"Runs all six detectors scoped to this user, in-process and synchronously. Defaults to a dry-run preview that returns the alerts that WOULD fire (per detector, with the decision payloads) without writing the feed, publishing events, or sending email. Set `dryRun: false` to actually fire.","operationId":"adminRunUserAlertDetector","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunUserDetectorRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunUserDetectorResponse"}}},"description":"Per-detector run summary (fired decisions on a dry-run)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Run the alert detector for one user (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/unread-count":{"get":{"operationId":"adminGetUserUnreadCount","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnreadCountResponse"}}},"description":"Unread count for the user's bell"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Get a user's unread alert count (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/watched-agents":{"get":{"operationId":"adminListUserWatchedAgents","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchedAgentsResponse"}}},"description":"Watched agents"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"List a user's watched agents (admin)","tags":["Admin"]},"post":{"operationId":"adminAddUserWatchedAgent","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddWatchedAgentRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertsOkResponse"}}},"description":"Added (idempotent)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Add a watched agent for a user (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/watched-agents/{id}":{"delete":{"operationId":"adminRemoveUserWatchedAgent","parameters":[{"in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Agent id to remove.","in":"path","name":"id","required":true,"schema":{"description":"Agent id to remove.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertsOkResponse"}}},"description":"Removed (idempotent)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Remove a watched agent for a user (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/watched-areas":{"get":{"operationId":"adminListUserWatchedAreas","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchedAreasResponse"}}},"description":"Watched areas"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"List a user's watched areas (admin)","tags":["Admin"]},"post":{"operationId":"adminAddUserWatchedArea","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddWatchedAreaRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchedAreasResponse"}}},"description":"The updated list"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Add a watched area for a user (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/watched-areas/{id}":{"delete":{"operationId":"adminRemoveUserWatchedArea","parameters":[{"in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Area id to remove.","in":"path","name":"id","required":true,"schema":{"description":"Area id to remove.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertsOkResponse"}}},"description":"Removed (idempotent)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Remove a watched area for a user (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/watched-documents":{"get":{"operationId":"adminListUserWatchedDocuments","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchedDocumentsResponse"}}},"description":"Watched documents"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"List a user's watched documents (admin)","tags":["Admin"]},"post":{"operationId":"adminAddUserWatchedDocument","parameters":[{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddWatchedDocumentRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchedDocumentsResponse"}}},"description":"The updated list of watched documents"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Add a watched document (property/sale/loan) for a user (admin)","tags":["Admin"]}},"/v1/admin/alerts/users/{userId}/watched-documents/{documentType}/{documentId}":{"delete":{"operationId":"adminRemoveUserWatchedDocument","parameters":[{"description":"The document kind.","in":"path","name":"documentType","required":true,"schema":{"description":"The document kind.","enum":["sale","property","loan"],"type":"string"}},{"description":"The document id.","in":"path","name":"documentId","required":true,"schema":{"description":"The document id.","type":"string"}},{"description":"Target user id.","in":"path","name":"userId","required":true,"schema":{"description":"Target user id.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertsOkResponse"}}},"description":"Removed (idempotent)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Remove a watched document for a user (admin)","tags":["Admin"]}},"/v1/admin/alerts/workspaces/{orgId}/log":{"get":{"description":"Every alert fired for any user in the workspace, newest first. Only alerts fired after the org was captured on each user's config appear.","operationId":"adminListWorkspaceAlertLog","parameters":[{"description":"Workspace / org id.","in":"path","name":"orgId","required":true,"schema":{"description":"Workspace / org id.","type":"string"}},{"description":"Max items to return (default 25).","in":"query","name":"limit","required":false,"schema":{"description":"Max items to return (default 25).","maximum":100,"minimum":1,"type":"integer"}},{"description":"Pagination cursor from a previous response.","in":"query","name":"cursor","required":false,"schema":{"description":"Pagination cursor from a previous response.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAlertLogResponse"}}},"description":"Paginated workspace feed"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"List a whole workspace's alert feed (admin)","tags":["Admin"]}},"/v1/admin/enrichments/cache":{"get":{"description":"Returns one page of rows from the DDB enrichment cache table. Optional `empty=true` filters server-side to rows the May 2026 parser-drift incident produced. **Cost note**: DDB Scan reads the whole table boundary regardless of the filter — admin-only.","operationId":"adminScanEnrichmentCache","parameters":[{"description":"Which row kind(s) to scan. Default `both`.","in":"query","name":"scope","required":false,"schema":{"$ref":"#/components/schemas/CacheScope"}},{"description":"When `true`, server-side filter to rows with `size(persons) = 0` — the shape produced by the May 2026 parser-drift incident.","in":"query","name":"empty","required":false,"schema":{"description":"When `true`, server-side filter to rows with `size(persons) = 0` — the shape produced by the May 2026 parser-drift incident.","enum":["true","false"],"type":"string"}},{"in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Page size (1-200, default 50).","in":"query","name":"limit","required":false,"schema":{"description":"Page size (1-200, default 50).","maximum":200,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichmentCacheScanResponse"}}},"description":"One page of cache rows"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Paginated scan of the enrichment cache (admin)","tags":["Admin"]}},"/v1/admin/enrichments/cache/bust":{"post":{"description":"Pass full row keys (as returned by `GET /v1/admin/enrichments/cache`). Mix internal and member keys in one call. Returns the count deleted and any keys DDB left in `UnprocessedItems` for the caller to retry.","operationId":"adminBustEnrichmentCacheRows","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichmentCacheBustRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichmentCacheBustResponse"}}},"description":"Delete summary"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Batch-delete a list of enrichment cache rows (admin)","tags":["Admin"]}},"/v1/admin/enrichments/cache/internal/{propertyId}":{"delete":{"description":"Idempotent — deleting a missing key is a success. Does NOT bust any `MEMBER#` rows that already cached a copy of this enrichment; use the batch `POST /v1/admin/enrichments/cache/bust` for that.","operationId":"adminDeleteInternalCacheRow","parameters":[{"in":"path","name":"propertyId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichmentCacheDeleteResponse"}}},"description":"Row deleted (or was already absent)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Bust a single internal cache row (admin)","tags":["Admin"]},"get":{"operationId":"adminGetInternalCacheRow","parameters":[{"in":"path","name":"propertyId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichmentCacheGetResponse"}}},"description":"The internal cache row (raw, including expired entries)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Row not found"}},"summary":"Inspect a single internal cache row (admin)","tags":["Admin"]}},"/v1/admin/enrichments/cache/member/{orgId}/{userId}/{propertyId}":{"delete":{"description":"Idempotent. Does NOT refund the original credit — the user's purchase remains on their account ledger; this just drops the cache row so the next enrich call re-fetches.","operationId":"adminDeleteMemberCacheRow","parameters":[{"in":"path","name":"orgId","required":true,"schema":{"type":"string"}},{"in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"in":"path","name":"propertyId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichmentCacheDeleteResponse"}}},"description":"Row deleted (or was already absent)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"Bust a single member entitlement row (admin)","tags":["Admin"]},"get":{"operationId":"adminGetMemberCacheRow","parameters":[{"in":"path","name":"orgId","required":true,"schema":{"type":"string"}},{"in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"in":"path","name":"propertyId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichmentCacheGetResponse"}}},"description":"The member entitlement row (raw, including expired)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Row not found"}},"summary":"Inspect a single member entitlement row (admin)","tags":["Admin"]}},"/v1/admin/enrichments/cache/property/{propertyId}":{"get":{"description":"Returns the internal property cache row and every member entitlement derived from it. Backed by the `byProperty` GSI — single Query, not a table scan. Rows written before the GSI shipped (no `propertyId` attribute) won't appear here until they next refresh.","operationId":"adminGetPropertyCacheChildren","parameters":[{"in":"path","name":"propertyId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichmentCachePropertyChildrenResponse"}}},"description":"Internal row + every member entitlement for this property"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"System admin role required"}},"summary":"List every cache row tied to a property (admin)","tags":["Admin"]}},"/v1/admin/jobs/{jobId}":{"get":{"description":"Returns any org's bulk job (delivery or enrichment) with a freshly signed download URL for its result file. Cross-org: signs against the job's own stored org. `resultsUrl` is null until the job is completed.","operationId":"adminGetBulkJob","parameters":[{"description":"Bulk job id (delivery or enrichment).","in":"path","name":"jobId","required":true,"schema":{"description":"Bulk job id (delivery or enrichment).","example":"job_01h...","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminBulkJobResponse"}}},"description":"The job"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not authenticated"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Admin role required"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"No job with that id (or it has aged past its TTL)"}},"summary":"Get a bulk job and a signed download URL (admin)","tags":["Admin: Jobs"]}},"/v1/agents":{"post":{"description":"Search and list individual real-estate agents with filters — one row per agent. Filter by name, location (state, city, zip), brokerage/office, and production metrics (sales volume, transaction units, price range), with sorting and cursor pagination. LOCATION SEMANTICS: the state/city/zip filters match ANY of an agent's location signals — their listed city/state, their office address(es), AND the markets where they actually closed transactions (production) — combined with OR. So an agent matches a searched location if their office OR their production is there. A search for city \"Long Beach\" can therefore return agents whose office or displayed primary market is in a different city/state, because they transacted in Long Beach. The `state`/`city` returned on each row reflect the agent's primary market and may differ from the searched location. (Use the `office` filter to match by brokerage/office name, and the per-agent city/county/state breakdown endpoints to rank an agent's volume within a specific market.) RANKING BY DEAL SIDE: combine a location filter with `sort` on `buyerVolume`/`buyerUnits` (or `sellerVolume`/`sellerUnits`, `dualVolume`/`dualUnits`) to rank agents by how active they are representing buyers vs. sellers in that market — e.g. sort `buyerVolume` descending for the most active buyer-side agents in a state or city. This is the per-agent record search: use it to find specific real-estate agents or build a filtered agent list. (For a single agent by ID use the agent detail endpoint.) If you only need how many agents match and not the records themselves, send the same request body to `countAgents`.","operationId":"listAgents","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentListResponse"}}},"description":"Paginated list of agents"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error. Includes unresolvable location filters: a `city`/`county`/`state`/`zip` value that does not match a recognized location returns 400 rather than an empty result set. Resolve the name with `instantSearch` (use an id from its `results.locations[]`) or `suggestLocations` (use the `id` of a `source: \"dictionary\"` result), then pass that id back as the filter value."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Location dictionary temporarily unavailable. Only returned for a NEGATED location filter (`neq`, or `not`), which cannot be honoured without resolving the excluded value — answering anyway would return the records you asked to exclude. Positive location filters are unaffected. Retry shortly; the filter value itself was not rejected."}},"summary":"Search agents with filters","tags":["Agents"]}},"/v1/agents/analytics/chart":{"post":{"operationId":"agentAnalyticsChart","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentChartRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChartResponse"}}},"description":"Chart data"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Configurable chart (measure × slice) over the agent's sales","tags":["Agents"]}},"/v1/agents/analytics/summary":{"post":{"operationId":"agentAnalyticsSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSummaryRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SidedSummaryResponse"}}},"description":"Sided summary with previous-period comparison"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Production summary with buyer/seller/dual split + previous period","tags":["Agents"]}},"/v1/agents/analytics/time-series":{"post":{"operationId":"agentAnalyticsTimeSeries","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentTimeSeriesRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SidedTimeSeriesResponse"}}},"description":"Time-series with side splits + previous period"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Agent volume/units over time with buyer/seller/dual split","tags":["Agents"]}},"/v1/agents/bulk-delivery":{"post":{"description":"Queues an ECS task that dumps every matching agents document to S3 in the requested format. Returns 202 with a jobId; poll `GET /v1/agents/bulk-delivery/{jobId}` for status + the signed download URL.\n\n**Row limit.** Deliveries of up to 1,000 rows need no entitlement. Above that, the org's `bulk-delivery.agents` entitlement is required and its scope (row ceiling, row filters, allowed fields) governs the delivery; without it the request is rejected with 403 `entitlement_missing`. Pass `limit` at or below the ceiling to deliver a capped subset of a broader query. Email support@modelmatch.com to request a limit increase.\n\nDelivery is billed at 1 credit per 100 rows regardless of entitlement.","operationId":"submitAgentsBulkDelivery","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/AgentListRequest"},{"additionalProperties":false,"properties":{"fields":{"description":"Optional output column projection, named by the response DTO fields (the same camelCase fields the list endpoint returns, e.g. `city`, `interestRate`). Intersected with the entitlement scope's allowedFields and the entity's full column set. If empty after intersection, falls back to all columns. It also SELECTS the opt-in columns, which are not part of the list DTO and are never delivered unless named here: `communityLending` (properties, originators, companies, branches) — the Community Lending neighborhood profile, identical to the block on the entity's detail endpoint; `parties` (properties) — the mortgage parties attributed to the parcel, by attribution scope; and `marketCount` / `countyCount` / `stateCount` / `zipCount` / `lenderCount` (originators) — the market-breadth rollups you can already filter on. In `csv` and `parquet` the two block columns are JSON-encoded cells; in `json` and `ndjson` they are nested objects.","items":{"minLength":1,"type":"string"},"type":"array"},"format":{"$ref":"#/components/schemas/BulkDeliveryFormat"},"limit":{"description":"Optional hard cap on the number of rows delivered — and therefore billed (1 credit / 100 rows). The job delivers the first `limit` rows in sort order (default newest-first) and bills only for those. If the query matches fewer than `limit`, all matches are delivered. Distinct from the page-size `size` field, which is ignored on this endpoint. The row ceiling still applies — 1,000 without the entity's bulk-delivery entitlement, or the entitlement's `maxRows` with it. A `limit` above the ceiling is rejected, but a `limit` at or below it lets you export a capped top-N even when the full match exceeds the ceiling — which is the intended way to run a broad query under the 1,000-row allowance.","example":1000,"exclusiveMinimum":true,"minimum":0,"type":"integer"}},"required":["format"],"type":"object"}]}}}},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliverySubmitResponse"}}},"description":"Job queued; ECS task launched"},"400":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/BulkDeliveryPreflightExceeded"}]}}},"description":"Validation failure OR delivery would exceed the entitlement's maxRows"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryInsufficientCredits"}}},"description":"Insufficient credits (balance < estimatedTotal / 100)"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryForbidden"}}},"description":"Delivery exceeds the 1,000-row limit available without the `bulk-delivery.agents` entitlement. Lower `limit`, narrow the filters, or contact support for a limit increase."},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Preflight / S3 / DDB / ECS launch failure"}},"summary":"Submit a bulk-delivery job for agents","tags":["Agents"]}},"/v1/agents/bulk-delivery/{jobId}":{"get":{"operationId":"getAgentsBulkDeliveryJob","parameters":[{"description":"Job ID returned by `POST /v1/agents/bulk-delivery`","in":"path","name":"jobId","required":true,"schema":{"description":"Job ID returned by `POST /v1/agents/bulk-delivery`","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryStatusResponse"}}},"description":"Job status (resultsUrl re-signed if completed)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Caller does not own this job"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Job not found (or expired past 30d TTL)"}},"summary":"Get bulk-delivery job status for agents","tags":["Agents"]}},"/v1/agents/count":{"post":{"description":"Return the exact number of agents matching the given filters. Accepts the same request body as `listAgents` (pagination and sort are ignored). Use this when you only need a total; to get the matching agents themselves, send the same request body to `listAgents`.","operationId":"countAgents","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountResponse"}}},"description":"Exact count of matching agents"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Location dictionary temporarily unavailable. Only returned for a NEGATED location filter (`neq`, or `not`), which cannot be honoured without resolving the excluded value — answering anyway would return the records you asked to exclude. Positive location filters are unaffected. Retry shortly; the filter value itself was not rejected."}},"summary":"Count agents matching filters","tags":["Agents"],"x-mm-records-via":"listAgents"}},"/v1/agents/{id}":{"get":{"operationId":"getAgent","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}},{"description":"Period for volume/units (default: last12Months)","in":"query","name":"period","required":false,"schema":{"allOf":[{"$ref":"#/components/schemas/Period"},{"description":"Period for volume/units (default: last12Months)"}]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentDetailResponse"}}},"description":"Agent detail"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Agent not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large"}},"summary":"Get agent by ID","tags":["Agents"]}},"/v1/agents/{id}/breakdowns/cities":{"post":{"operationId":"agentCities","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the agent's sales by cities"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"City volume breakdown across the agent's sales","tags":["Agents"]}},"/v1/agents/{id}/breakdowns/companies":{"post":{"operationId":"agentCompanies","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoredBreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Pre-aggregated companies breakdown from the agent's scored doc"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Mortgage companies the agent dealt with (pre-aggregated)","tags":["Agents"]}},"/v1/agents/{id}/breakdowns/counties":{"post":{"operationId":"agentCounties","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the agent's sales by counties"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"County (FIPS) volume breakdown","tags":["Agents"]}},"/v1/agents/{id}/breakdowns/lenders":{"post":{"operationId":"agentLenders","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoredBreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Pre-aggregated lenders breakdown from the agent's scored doc"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Raw-name lenders encountered (pre-aggregated)","tags":["Agents"]}},"/v1/agents/{id}/breakdowns/offices":{"post":{"operationId":"agentOffices","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the agent's sales by offices"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Listing offices the agent has closed through","tags":["Agents"]}},"/v1/agents/{id}/breakdowns/originators":{"post":{"operationId":"agentOriginators","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoredBreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Pre-aggregated originators breakdown from the agent's scored doc"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Loan officers the agent worked with (pre-aggregated)","tags":["Agents"]}},"/v1/agents/{id}/breakdowns/states":{"post":{"operationId":"agentStates","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the agent's sales by states"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"State volume breakdown","tags":["Agents"]}},"/v1/agents/{id}/breakdowns/zip-codes":{"post":{"operationId":"agentZipCodes","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the agent's sales by zip-codes"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Zip-code volume breakdown","tags":["Agents"]}},"/v1/agents/{id}/markets":{"post":{"description":"Rank the ZIP markets one real-estate agent works, with volume, transaction counts and mean sale price per market, plus a weighted summary across the whole footprint. Optionally narrow to a ZIP list or a date window. REACH, NOT MARKET SHARE: an agent belongs to every market they touch — where their office is AND everywhere they have transacted — so one agent is counted in several markets at once. Per-market agent counts therefore over-sum: they cannot be added together, and dividing one into a total does not produce a market share. The only percentage returned, `shareOfScope`, is each market's share of this agent's volume across the scope requested and sums to 100 over that scope; there is no share-of-whole-book figure, because the transaction records carry no per-agent total to divide by. TWO COUNTS, ON PURPOSE: `transactions` counts transaction records; `units` counts the ones carrying a price, which are the records behind `volume` and `avgSalePrice`. Roughly half of an agent's records are priced, so dividing volume by `transactions` understates the average by about 2×. Figures are computed live from the agent's transaction records — an agent record carries no stored market rollup — and are ranked across their busiest ZIP markets. When a ZIP scope returns no markets, `reach.presentInScope` distinguishes 'works there, nothing closed in the window' from 'not present at all'. The summary also carries a Community Lending mix: what kind of neighborhood these markets are, weighted by the agent's activity in each. These are U.S. Census tract-level aggregates describing whole neighborhoods — never an individual, household or client attribute — and on this surface the basis is always the markets in scope, since an agent record carries no stored neighborhood rollup.","operationId":"agentMarkets","parameters":[{"description":"Agent ID","in":"path","name":"id","required":true,"schema":{"description":"Agent ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentMarketsRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentMarketsResponse"}}},"description":"The agent's blended market footprint"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"The ZIP markets this agent works, blended","tags":["Agents"]}},"/v1/agents/{id}/properties":{"post":{"operationId":"agentProperties","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRelationRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentPropertiesResponse"}}},"description":"Paginated list of properties for this agent"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Properties this agent has transacted on","tags":["Agents"]}},"/v1/agents/{id}/related":{"get":{"description":"Return the ids of records of another type that are linked to this record. Links resolve by identifier, strongest identifier first, and equally-trusted identifiers are combined — a company's linked loans cover every role it holds on a loan, not just the first one found. The response reports which strength was used: `primary` is the canonical identifier for that pair, `secondary` is a real but weaker alternate used only when the record carries nothing better. This is a lightweight index: it returns ids and a count, not full records. For filtering, sorting, pagination and full detail, use the named endpoint for the pair (for example the originator loans endpoint) and fetch records by id.","operationId":"agentRelated","parameters":[{"description":"Agent id","in":"path","name":"id","required":true,"schema":{"description":"Agent id","type":"string"}},{"description":"Type of record to link to","in":"query","name":"to","required":true,"schema":{"description":"Type of record to link to","enum":["loans","sales"],"type":"string"}},{"description":"Maximum ids to return (default 25, max 200)","in":"query","name":"limit","required":false,"schema":{"description":"Maximum ids to return (default 25, max 200)","maximum":200,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelatedResponse"}}},"description":"Linked record ids"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Record not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Records linked to this one","tags":["Related"]}},"/v1/agents/{id}/sales":{"post":{"operationId":"agentSales","parameters":[{"description":"Agent document ID","in":"path","name":"id","required":true,"schema":{"description":"Agent document ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRelationRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSalesResponse"}}},"description":"Paginated list of sales for this agent"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Sales transactions where this agent was listing or selling side","tags":["Agents"]}},"/v1/alerts/conditions":{"get":{"operationId":"getAlertConditions","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertConditionsResponse"}}},"description":"Per-trigger flags + tunables (defaults if none saved)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Get your alert settings","tags":["Alerts"]},"put":{"operationId":"updateAlertConditions","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAlertConditionsRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertConditionsResponse"}}},"description":"The saved settings"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Update your alert settings","tags":["Alerts"]}},"/v1/alerts/digests":{"get":{"operationId":"listAlertDigests","parameters":[{"description":"Max items to return (default 25).","in":"query","name":"limit","required":false,"schema":{"description":"Max items to return (default 25).","maximum":100,"minimum":1,"type":"integer"}},{"description":"Pagination cursor from a previous response.","in":"query","name":"cursor","required":false,"schema":{"description":"Pagination cursor from a previous response.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertDigestResponse"}}},"description":"Paginated digest feed"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List your alert digests (newest first)","tags":["Alerts"]}},"/v1/alerts/digests/{id}/read":{"post":{"operationId":"markAlertDigestRead","parameters":[{"description":"Digest id (from the feed).","in":"path","name":"id","required":true,"schema":{"description":"Digest id (from the feed).","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertsOkResponse"}}},"description":"Marked read (idempotent)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Mark one digest read","tags":["Alerts"]}},"/v1/alerts/log":{"get":{"operationId":"listAlertLog","parameters":[{"description":"Max items to return (default 25).","in":"query","name":"limit","required":false,"schema":{"description":"Max items to return (default 25).","maximum":100,"minimum":1,"type":"integer"}},{"description":"Pagination cursor from a previous response.","in":"query","name":"cursor","required":false,"schema":{"description":"Pagination cursor from a previous response.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertLogResponse"}}},"description":"Paginated alert feed"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List your alerts (newest first)","tags":["Alerts"]}},"/v1/alerts/log/mark-all-read":{"post":{"operationId":"markAllAlertsRead","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertsOkResponse"}}},"description":"Unread count reset to 0"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Clear the unread badge","tags":["Alerts"]}},"/v1/alerts/log/{id}/read":{"post":{"operationId":"markAlertRead","parameters":[{"description":"Alert id (from the feed).","in":"path","name":"id","required":true,"schema":{"description":"Alert id (from the feed).","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertsOkResponse"}}},"description":"Marked read (idempotent)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Mark one alert read","tags":["Alerts"]}},"/v1/alerts/preview":{"post":{"description":"Runs all six detectors scoped to your own token, in-process and synchronously, as a dry-run: returns the alerts that WOULD fire (per detector, with the decision payloads) without writing the feed, publishing events, or sending email.","operationId":"previewAlerts","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewAlertsRequest"}}},"required":false},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunUserDetectorResponse"}}},"description":"Per-detector dry-run summary (the decisions that would fire)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Preview the alerts that would fire for you","tags":["Alerts"]}},"/v1/alerts/unread-count":{"get":{"operationId":"getAlertUnreadCount","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnreadCountResponse"}}},"description":"Unread count for the bell"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Get your unread alert count","tags":["Alerts"]}},"/v1/alerts/watched-agents":{"get":{"operationId":"listWatchedAgents","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchedAgentsResponse"}}},"description":"Watched agents (hand-added + auto-derived)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List the agents you watch","tags":["Alerts"]},"post":{"operationId":"addWatchedAgent","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddWatchedAgentRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertsOkResponse"}}},"description":"Agent added (idempotent)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Watch an agent","tags":["Alerts"]}},"/v1/alerts/watched-agents/{id}":{"delete":{"operationId":"removeWatchedAgent","parameters":[{"description":"Agent id to remove.","in":"path","name":"id","required":true,"schema":{"description":"Agent id to remove.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertsOkResponse"}}},"description":"Agent removed (idempotent)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Stop watching an agent","tags":["Alerts"]}},"/v1/alerts/watched-areas":{"get":{"operationId":"listWatchedAreas","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchedAreasResponse"}}},"description":"Watched areas"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List the areas you watch","tags":["Alerts"]},"post":{"operationId":"addWatchedArea","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddWatchedAreaRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchedAreasResponse"}}},"description":"The updated list of watched areas"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Watch an area","tags":["Alerts"]}},"/v1/alerts/watched-areas/{id}":{"delete":{"operationId":"removeWatchedArea","parameters":[{"description":"Area id (from the list).","in":"path","name":"id","required":true,"schema":{"description":"Area id (from the list).","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertsOkResponse"}}},"description":"Area removed (idempotent)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Stop watching an area","tags":["Alerts"]}},"/v1/alerts/watched-documents":{"get":{"operationId":"listWatchedDocuments","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchedDocumentsResponse"}}},"description":"Watched documents"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List the documents you watch","tags":["Alerts"]},"post":{"operationId":"addWatchedDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddWatchedDocumentRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchedDocumentsResponse"}}},"description":"The updated list of watched documents"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Watch a document","tags":["Alerts"]}},"/v1/alerts/watched-documents/{documentType}/{documentId}":{"delete":{"operationId":"removeWatchedDocument","parameters":[{"description":"The document kind.","in":"path","name":"documentType","required":true,"schema":{"description":"The document kind.","enum":["sale","property","loan"],"type":"string"}},{"description":"The document id.","in":"path","name":"documentId","required":true,"schema":{"description":"The document id.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertsOkResponse"}}},"description":"Document removed (idempotent)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Stop watching a document","tags":["Alerts"]}},"/v1/branches":{"post":{"description":"Search NMLS-registered mortgage company branch offices (not MLS real estate offices — use listOffices for those). Returns branch name, address, parent company, managers, and NMLS ID. Each row carries branch-level production metrics for the selected period. If you only need how many branches match and not the records themselves, send the same request body to `countBranches`.","operationId":"listBranches","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchListResponse"}}},"description":"Paginated list of branches"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error. Includes unresolvable location filters: a `city`/`county`/`state`/`zip` value that does not match a recognized location returns 400 rather than an empty result set. Resolve the name with `instantSearch` (use an id from its `results.locations[]`) or `suggestLocations` (use the `id` of a `source: \"dictionary\"` result), then pass that id back as the filter value."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Search branches with filters","tags":["Branches"]}},"/v1/branches/bulk-delivery":{"post":{"description":"Queues an ECS task that dumps every matching branches document to S3 in the requested format. Returns 202 with a jobId; poll `GET /v1/branches/bulk-delivery/{jobId}` for status + the signed download URL.\n\n**Row limit.** Deliveries of up to 1,000 rows need no entitlement. Above that, the org's `bulk-delivery.branches` entitlement is required and its scope (row ceiling, row filters, allowed fields) governs the delivery; without it the request is rejected with 403 `entitlement_missing`. Pass `limit` at or below the ceiling to deliver a capped subset of a broader query. Email support@modelmatch.com to request a limit increase.\n\nDelivery is billed at 1 credit per 100 rows regardless of entitlement.","operationId":"submitBranchesBulkDelivery","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BranchListRequest"},{"additionalProperties":false,"properties":{"fields":{"description":"Optional output column projection, named by the response DTO fields (the same camelCase fields the list endpoint returns, e.g. `city`, `interestRate`). Intersected with the entitlement scope's allowedFields and the entity's full column set. If empty after intersection, falls back to all columns. It also SELECTS the opt-in columns, which are not part of the list DTO and are never delivered unless named here: `communityLending` (properties, originators, companies, branches) — the Community Lending neighborhood profile, identical to the block on the entity's detail endpoint; `parties` (properties) — the mortgage parties attributed to the parcel, by attribution scope; and `marketCount` / `countyCount` / `stateCount` / `zipCount` / `lenderCount` (originators) — the market-breadth rollups you can already filter on. In `csv` and `parquet` the two block columns are JSON-encoded cells; in `json` and `ndjson` they are nested objects.","items":{"minLength":1,"type":"string"},"type":"array"},"format":{"$ref":"#/components/schemas/BulkDeliveryFormat"},"limit":{"description":"Optional hard cap on the number of rows delivered — and therefore billed (1 credit / 100 rows). The job delivers the first `limit` rows in sort order (default newest-first) and bills only for those. If the query matches fewer than `limit`, all matches are delivered. Distinct from the page-size `size` field, which is ignored on this endpoint. The row ceiling still applies — 1,000 without the entity's bulk-delivery entitlement, or the entitlement's `maxRows` with it. A `limit` above the ceiling is rejected, but a `limit` at or below it lets you export a capped top-N even when the full match exceeds the ceiling — which is the intended way to run a broad query under the 1,000-row allowance.","example":1000,"exclusiveMinimum":true,"minimum":0,"type":"integer"}},"required":["format"],"type":"object"}]}}}},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliverySubmitResponse"}}},"description":"Job queued; ECS task launched"},"400":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/BulkDeliveryPreflightExceeded"}]}}},"description":"Validation failure OR delivery would exceed the entitlement's maxRows"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryInsufficientCredits"}}},"description":"Insufficient credits (balance < estimatedTotal / 100)"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryForbidden"}}},"description":"Delivery exceeds the 1,000-row limit available without the `bulk-delivery.branches` entitlement. Lower `limit`, narrow the filters, or contact support for a limit increase."},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Preflight / S3 / DDB / ECS launch failure"}},"summary":"Submit a bulk-delivery job for branches","tags":["Branches"]}},"/v1/branches/bulk-delivery/{jobId}":{"get":{"operationId":"getBranchesBulkDeliveryJob","parameters":[{"description":"Job ID returned by `POST /v1/branches/bulk-delivery`","in":"path","name":"jobId","required":true,"schema":{"description":"Job ID returned by `POST /v1/branches/bulk-delivery`","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryStatusResponse"}}},"description":"Job status (resultsUrl re-signed if completed)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Caller does not own this job"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Job not found (or expired past 30d TTL)"}},"summary":"Get bulk-delivery job status for branches","tags":["Branches"]}},"/v1/branches/count":{"post":{"description":"Return the exact number of branches matching the given filters. Accepts the same request body as `listBranches` (pagination and sort are ignored). Use this when you only need a total; to get the matching branches themselves, send the same request body to `listBranches`.","operationId":"countBranches","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountResponse"}}},"description":"Exact count of matching branches"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Count branches matching filters","tags":["Branches"],"x-mm-records-via":"listBranches"}},"/v1/branches/{nmlsId}":{"get":{"description":"Retrieve full details for a single NMLS mortgage branch including name, address, parent company, managers, trade names, licensing, and branch-level production for the selected period.","operationId":"getBranch","parameters":[{"description":"Branch NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Branch NMLS ID","type":"string"}},{"description":"Period for production metrics (default: last12Months). Does NOT apply to `teamSize`, which is a current snapshot and reads the same on every period.","in":"query","name":"period","required":false,"schema":{"allOf":[{"$ref":"#/components/schemas/Period"},{"description":"Period for production metrics (default: last12Months). Does NOT apply to `teamSize`, which is a current snapshot and reads the same on every period."}]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchDetailResponse"}}},"description":"Branch detail"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Branch not found"}},"summary":"Get branch by NMLS ID","tags":["Branches"]}},"/v1/branches/{nmlsId}/breakdowns/cities":{"post":{"description":"Ranks the cities this branch's loans were secured in, by volume — the branch's real lending footprint rather than its parent company's. Labels are Title Case so they match the city breakdowns on every other entity.","operationId":"branchCities","parameters":[{"description":"Branch NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Branch NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of this branch's loans by cities"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"City volume breakdown across this branch's loans","tags":["Branches"]}},"/v1/branches/{nmlsId}/breakdowns/counties":{"post":{"description":"Ranks the counties this branch's loans were secured in, by volume. Labels are county codes on this surface — the same axis every other county breakdown uses, so the two are directly comparable.","operationId":"branchCounties","parameters":[{"description":"Branch NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Branch NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of this branch's loans by counties"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"County volume breakdown across this branch's loans","tags":["Branches"]}},"/v1/branches/{nmlsId}/breakdowns/lenders":{"post":{"description":"Ranks the lenders this branch's loans funded through, by volume. Pass an item's `id` — not its `label` — back as a `lender` filter value; `label` is the display name.","operationId":"branchLenders","parameters":[{"description":"Branch NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Branch NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of this branch's loans by lenders"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Lenders this branch originated through","tags":["Branches"]}},"/v1/branches/{nmlsId}/breakdowns/originators":{"post":{"description":"Ranks the loan officers whose loans public record attributes to this branch, by volume. Each label is the LO's NMLS ID, so it chains straight into `GET /v1/originators/{nmlsId}`. This is the branch's RECORDED roster, not its licensing roster: it answers who actually wrote loans here in the period, which is narrower than everyone registered to the branch and can include someone who has since moved. For the licensed managers on file, read `managers` on `GET /v1/branches/{nmlsId}`.","operationId":"branchOriginators","parameters":[{"description":"Branch NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Branch NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of this branch's loans by originators"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Loan officers who wrote this branch's loans","tags":["Branches"]}},"/v1/branches/{nmlsId}/breakdowns/states":{"post":{"description":"Ranks the states this branch's loans were secured in, by volume. Labels are two-letter state abbreviations. This is where the branch actually transacted, which is narrower than where it is licensed — licensed states are returned by `GET /v1/branches/{nmlsId}`.","operationId":"branchStates","parameters":[{"description":"Branch NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Branch NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of this branch's loans by states"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"State volume breakdown across this branch's loans","tags":["Branches"]}},"/v1/branches/{nmlsId}/loans":{"post":{"description":"Returns the individual loans attributed to this branch office — the branch's own book, not its parent company's. Accepts the same filters, sorts and pagination as the main loan search. Attribution comes from public record, so this is the branch's recorded footprint and can be smaller than the production totals on `GET /v1/branches/{nmlsId}`.","operationId":"branchLoans","parameters":[{"description":"Branch NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Branch NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanListResponse"}}},"description":"Paginated list of loans written by this branch"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Loans written by this branch","tags":["Branches"]}},"/v1/companies":{"post":{"description":"Search and list individual mortgage companies with filters — one row per company. Filter by name, NMLS ID, location (state, county, city, zip), and production metrics (loan volume, units, market share) by period and geography, with sorting and cursor pagination. This is the per-company record search: use it to find specific mortgage lenders/companies or build a filtered company list. (For a single company by ID use the company detail endpoint.) If you only need how many companies match and not the records themselves, send the same request body to `countCompanies`.","operationId":"listCompanies","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListResponse"}}},"description":"Paginated list of companies"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error. Includes unresolvable location filters: a `city`/`county`/`state`/`zip` value that does not match a recognized location returns 400 rather than an empty result set. Resolve the name with `instantSearch` (use an id from its `results.locations[]`) or `suggestLocations` (use the `id` of a `source: \"dictionary\"` result), then pass that id back as the filter value."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Search companies with filters","tags":["Companies"]}},"/v1/companies/analytics/chart":{"post":{"operationId":"companyAnalyticsChart","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyChartRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChartResponse"}}},"description":"Chart data. Money measures (`volume`, `avgSalePrice`, `avgListPrice`) are sentinel-guarded. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Configurable chart (measure × slice) over company's loans","tags":["Companies"]}},"/v1/companies/analytics/summary":{"post":{"operationId":"companyAnalyticsSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySummaryRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleSummaryResponse"}}},"description":"Current + previous-period summary"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Production summary with previous-period comparison","tags":["Companies"]}},"/v1/companies/analytics/time-series":{"post":{"operationId":"companyAnalyticsTimeSeries","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyTimeSeriesRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleTimeSeriesResponse"}}},"description":"Time-series with previous-period comparison"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Company volume / units over time","tags":["Companies"]}},"/v1/companies/bulk-delivery":{"post":{"description":"Queues an ECS task that dumps every matching companies document to S3 in the requested format. Returns 202 with a jobId; poll `GET /v1/companies/bulk-delivery/{jobId}` for status + the signed download URL.\n\n**Row limit.** Deliveries of up to 1,000 rows need no entitlement. Above that, the org's `bulk-delivery.companies` entitlement is required and its scope (row ceiling, row filters, allowed fields) governs the delivery; without it the request is rejected with 403 `entitlement_missing`. Pass `limit` at or below the ceiling to deliver a capped subset of a broader query. Email support@modelmatch.com to request a limit increase.\n\nDelivery is billed at 1 credit per 100 rows regardless of entitlement.","operationId":"submitCompaniesBulkDelivery","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/CompanyListRequest"},{"additionalProperties":false,"properties":{"fields":{"description":"Optional output column projection, named by the response DTO fields (the same camelCase fields the list endpoint returns, e.g. `city`, `interestRate`). Intersected with the entitlement scope's allowedFields and the entity's full column set. If empty after intersection, falls back to all columns. It also SELECTS the opt-in columns, which are not part of the list DTO and are never delivered unless named here: `communityLending` (properties, originators, companies, branches) — the Community Lending neighborhood profile, identical to the block on the entity's detail endpoint; `parties` (properties) — the mortgage parties attributed to the parcel, by attribution scope; and `marketCount` / `countyCount` / `stateCount` / `zipCount` / `lenderCount` (originators) — the market-breadth rollups you can already filter on. In `csv` and `parquet` the two block columns are JSON-encoded cells; in `json` and `ndjson` they are nested objects.","items":{"minLength":1,"type":"string"},"type":"array"},"format":{"$ref":"#/components/schemas/BulkDeliveryFormat"},"limit":{"description":"Optional hard cap on the number of rows delivered — and therefore billed (1 credit / 100 rows). The job delivers the first `limit` rows in sort order (default newest-first) and bills only for those. If the query matches fewer than `limit`, all matches are delivered. Distinct from the page-size `size` field, which is ignored on this endpoint. The row ceiling still applies — 1,000 without the entity's bulk-delivery entitlement, or the entitlement's `maxRows` with it. A `limit` above the ceiling is rejected, but a `limit` at or below it lets you export a capped top-N even when the full match exceeds the ceiling — which is the intended way to run a broad query under the 1,000-row allowance.","example":1000,"exclusiveMinimum":true,"minimum":0,"type":"integer"}},"required":["format"],"type":"object"}]}}}},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliverySubmitResponse"}}},"description":"Job queued; ECS task launched"},"400":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/BulkDeliveryPreflightExceeded"}]}}},"description":"Validation failure OR delivery would exceed the entitlement's maxRows"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryInsufficientCredits"}}},"description":"Insufficient credits (balance < estimatedTotal / 100)"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryForbidden"}}},"description":"Delivery exceeds the 1,000-row limit available without the `bulk-delivery.companies` entitlement. Lower `limit`, narrow the filters, or contact support for a limit increase."},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Preflight / S3 / DDB / ECS launch failure"}},"summary":"Submit a bulk-delivery job for companies","tags":["Companies"]}},"/v1/companies/bulk-delivery/{jobId}":{"get":{"operationId":"getCompaniesBulkDeliveryJob","parameters":[{"description":"Job ID returned by `POST /v1/companies/bulk-delivery`","in":"path","name":"jobId","required":true,"schema":{"description":"Job ID returned by `POST /v1/companies/bulk-delivery`","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryStatusResponse"}}},"description":"Job status (resultsUrl re-signed if completed)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Caller does not own this job"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Job not found (or expired past 30d TTL)"}},"summary":"Get bulk-delivery job status for companies","tags":["Companies"]}},"/v1/companies/count":{"post":{"description":"Return the exact number of companies matching the given filters. Accepts the same request body as `listCompanies` (pagination and sort are ignored). Use this when you only need a total; to get the matching companies themselves, send the same request body to `listCompanies`.","operationId":"countCompanies","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountResponse"}}},"description":"Exact count of matching companies"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Count companies matching filters","tags":["Companies"],"x-mm-records-via":"listCompanies"}},"/v1/companies/{id}/related":{"get":{"description":"Return the ids of records of another type that are linked to this record. Links resolve by identifier, strongest identifier first, and equally-trusted identifiers are combined — a company's linked loans cover every role it holds on a loan, not just the first one found. The response reports which strength was used: `primary` is the canonical identifier for that pair, `secondary` is a real but weaker alternate used only when the record carries nothing better. This is a lightweight index: it returns ids and a count, not full records. For filtering, sorting, pagination and full detail, use the named endpoint for the pair (for example the originator loans endpoint) and fetch records by id.","operationId":"companyRelated","parameters":[{"description":"Company NMLS ID","in":"path","name":"id","required":true,"schema":{"description":"Company NMLS ID","type":"string"}},{"description":"Type of record to link to","in":"query","name":"to","required":true,"schema":{"description":"Type of record to link to","enum":["loans","originators","properties"],"type":"string"}},{"description":"Maximum ids to return (default 25, max 200)","in":"query","name":"limit","required":false,"schema":{"description":"Maximum ids to return (default 25, max 200)","maximum":200,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelatedResponse"}}},"description":"Linked record ids"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Record not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Records linked to this one","tags":["Related"]}},"/v1/companies/{nmlsId}":{"get":{"operationId":"getCompany","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}},{"description":"Period for production metrics (default: last12Months)","in":"query","name":"period","required":false,"schema":{"allOf":[{"$ref":"#/components/schemas/Period"},{"description":"Period for production metrics (default: last12Months)"}]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDetailResponse"}}},"description":"Company detail"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Company not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large"}},"summary":"Get company by NMLS ID","tags":["Companies"]}},"/v1/companies/{nmlsId}/branches":{"post":{"operationId":"companyBranches","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyBranchesResponse"}}},"description":"Paginated list of branches"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Branch locations for this company","tags":["Companies"]}},"/v1/companies/{nmlsId}/breakdowns/agents":{"post":{"description":"Ranks the real-estate agents on the selling side of this company's loans, by volume. Buckets whose name is an MLS placeholder for \"no selling agent recorded\" (`non member`, `non listed agent`, and ~140 board-specific spellings) are excluded rather than ranked as agents — they are not people and cannot be resolved with `GET /v1/agents/{id}`. Percentages are shares of the company's whole loan population, so they do not sum to 100 across the page.","operationId":"companyAgents","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the company's loans by agents"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Real-estate agents who co-closed with this company's LOs","tags":["Companies"]}},"/v1/companies/{nmlsId}/breakdowns/brokers":{"post":{"operationId":"companyBrokers","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the company's loans by brokers"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Broker shops that originated loans funding through this company. For a wholesale/TPO lender this is its top broker partners.","tags":["Companies"]}},"/v1/companies/{nmlsId}/breakdowns/cities":{"post":{"operationId":"companyCities","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the company's loans by cities"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"City volume breakdown across this company's loans","tags":["Companies"]}},"/v1/companies/{nmlsId}/breakdowns/counties":{"post":{"operationId":"companyCounties","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the company's loans by counties"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"County (FIPS) volume breakdown across this company's loans","tags":["Companies"]}},"/v1/companies/{nmlsId}/breakdowns/lenders":{"post":{"operationId":"companyLenders","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the company's loans by lenders"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Lenders this company originated through","tags":["Companies"]}},"/v1/companies/{nmlsId}/breakdowns/offices":{"post":{"operationId":"companyOffices","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the company's loans by offices"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Broker offices this company originated through","tags":["Companies"]}},"/v1/companies/{nmlsId}/breakdowns/originators":{"post":{"operationId":"companyOriginators","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the company's loans by originators"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Loan officers who originated through this company","tags":["Companies"]}},"/v1/companies/{nmlsId}/breakdowns/states":{"post":{"operationId":"companyStates","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the company's loans by states"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"State volume breakdown across this company's loans","tags":["Companies"]}},"/v1/companies/{nmlsId}/breakdowns/zip-codes":{"post":{"operationId":"companyZipCodes","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the company's loans by zip-codes"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Zip-code volume breakdown across this company's loans","tags":["Companies"]}},"/v1/companies/{nmlsId}/markets":{"post":{"description":"The company's market footprint for a period: a units-weighted summary, the ZIP-level markets, and the city / county / state rollups, computed from the company's recorded transactions. Optionally narrow to a set of ZIP codes and/or a custom date window. Shares are percentages on a 0–100 scale. The summary also carries a Community Lending mix — what kind of neighborhood the book lands in, as U.S. Census tract-level aggregates describing whole neighborhoods, never individual or applicant attributes. Unfiltered, it is the company's own whole-period mix; any ZIP, date or transaction filter recomputes it over the markets in scope, and `summary.communityLending.basis` says which you got.","operationId":"companyMarkets","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyMarketsRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyMarketsResponse"}}},"description":"Blended market footprint"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error. Includes unresolvable location filters: a `city`/`county`/`state`/`zip` value that does not match a recognized location returns 400 rather than an empty result set. Resolve the name with `instantSearch` (use an id from its `results.locations[]`) or `suggestLocations` (use the `id` of a `source: \"dictionary\"` result), then pass that id back as the filter value."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Where a company lends — blended market footprint","tags":["Companies"]}},"/v1/companies/{nmlsId}/sponsored-individuals":{"post":{"operationId":"companySponsoredIndividuals","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySponsoredIndividualsResponse"}}},"description":"Paginated list of sponsored individuals"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Loan originators sponsored by this company","tags":["Companies"]}},"/v1/companies/{nmlsId}/sponsorship-movement":{"post":{"operationId":"companySponsorshipMovement","parameters":[{"description":"Company NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Company NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySponsorshipMovementRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySponsorshipMovementResponse"}}},"description":"Movement analysis"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Analyze LO arrivals and departures for a company","tags":["Companies"]}},"/v1/crm/activity":{"delete":{"operationId":"deleteCrmNote","requestBody":{"content":{"application/json":{"schema":{"properties":{"id":{"minLength":1,"type":"string"}},"required":["id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmDeleteNoteResult"}}},"description":"Whether the note was soft-deleted."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Soft-delete a note","tags":["CRM"]},"get":{"operationId":"listCrmActivity","parameters":[{"description":"The CRM record id whose timeline to read.","in":"query","name":"entityId","required":true,"schema":{"description":"The CRM record id whose timeline to read.","minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmActivityList"}}},"description":"The record's timeline entries, newest first."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List a record's activity timeline (newest first)","tags":["CRM"]},"patch":{"operationId":"editCrmNote","requestBody":{"content":{"application/json":{"schema":{"properties":{"body":{"type":"string"},"bodyHtml":{"nullable":true,"type":"string"},"grantRecordAccessUserIds":{"items":{"type":"string"},"type":"array"},"id":{"minLength":1,"type":"string"},"listId":{"nullable":true,"type":"string"},"recordName":{"type":"string"},"recordUrl":{"deprecated":true,"description":"Ignored — the record link is server-built.","type":"string"}},"required":["id","body"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmEditNoteResult"}}},"description":"Whether the note was updated, plus its record + prior body."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Edit a note's body","tags":["CRM"]},"post":{"operationId":"addCrmNote","requestBody":{"content":{"application/json":{"schema":{"properties":{"body":{"type":"string"},"bodyHtml":{"nullable":true,"type":"string"},"callId":{"nullable":true,"type":"string"},"entityId":{"minLength":1,"type":"string"},"grantRecordAccessUserIds":{"items":{"type":"string"},"type":"array"},"listId":{"nullable":true,"type":"string"},"parentId":{"nullable":true,"type":"string"},"recordName":{"type":"string"},"recordUrl":{"deprecated":true,"description":"Ignored — the record link is server-built.","type":"string"}},"required":["entityId","body"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmAddNoteResult"}}},"description":"The new note's id + its resolved thread root (null if top-level)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Append a note to a record's timeline","tags":["CRM"]}},"/v1/crm/activity/referenced":{"get":{"operationId":"listCrmReferencedActivity","parameters":[{"description":"The CRM record whose referenced (trickled-up) activity to read.","in":"query","name":"entityId","required":true,"schema":{"description":"The CRM record whose referenced (trickled-up) activity to read.","minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmReferencedActivityList"}}},"description":"Notes authored on other records that reference this record, newest first."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List notes from other records that reference this one (trickled up)","tags":["CRM"]}},"/v1/crm/caller-ids":{"delete":{"operationId":"deleteCrmCallerId","parameters":[{"in":"query","name":"id","required":true,"schema":{"minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmDeleteCallerIdResult"}}},"description":"Whether the caller ID was removed."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Remove a caller ID from the registry","tags":["CRM"]},"get":{"operationId":"listCrmCallerIds","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmCallerIdList"}}},"description":"The user's caller IDs + whether Twilio is configured."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List the current user's caller IDs","tags":["CRM"]},"patch":{"operationId":"setDefaultCrmCallerId","requestBody":{"content":{"application/json":{"schema":{"properties":{"id":{"maxLength":128,"minLength":1,"type":"string"}},"required":["id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmSetDefaultCallerIdResult"}}},"description":"Whether the default was set."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Make a verified caller ID the default","tags":["CRM"]},"post":{"operationId":"actionCrmCallerId","requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"properties":{"action":{"enum":["start"],"type":"string"},"friendlyName":{"maxLength":64,"type":"string"},"phoneNumber":{"maxLength":32,"minLength":7,"type":"string"}},"required":["action","phoneNumber"],"type":"object"},{"properties":{"action":{"enum":["check"],"type":"string"},"id":{"maxLength":128,"minLength":1,"type":"string"}},"required":["action","id"],"type":"object"}]}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmCallerIdActionResult"}}},"description":"The caller-ID row (+ the verification code on start)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Start caller-ID verification or re-check its outcome","tags":["CRM"]}},"/v1/crm/calls":{"get":{"operationId":"getCrmCall","parameters":[{"in":"query","name":"id","required":true,"schema":{"minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmPollCallResult"}}},"description":"The call row."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Poll one call's status (syncs + finalizes on terminal)","tags":["CRM"]},"patch":{"operationId":"hangupCrmCall","requestBody":{"content":{"application/json":{"schema":{"properties":{"id":{"maxLength":128,"minLength":1,"type":"string"}},"required":["id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmHangupCallResult"}}},"description":"The call row."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Hang up an in-flight call","tags":["CRM"]},"post":{"operationId":"placeCrmCall","requestBody":{"content":{"application/json":{"schema":{"properties":{"callerIdId":{"maxLength":128,"minLength":1,"type":"string"},"entityId":{"maxLength":128,"minLength":1,"type":"string"},"record":{"type":"boolean"},"toNumber":{"maxLength":32,"minLength":7,"type":"string"}},"required":["entityId","toNumber","callerIdId"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmPlaceCallResult"}}},"description":"The call row."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Place an outbound bridge call","tags":["CRM"]}},"/v1/crm/calls/active":{"get":{"operationId":"getCrmActiveCall","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmActiveCallResult"}}},"description":"The live call to resume, or null."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"The current user's still-live call (for reload resume)","tags":["CRM"]}},"/v1/crm/calls/analysis":{"post":{"operationId":"setCrmCallAnalysis","requestBody":{"content":{"application/json":{"schema":{"properties":{"actions":{"items":{"oneOf":[{"properties":{"dueInDays":{"maximum":365,"minimum":0,"type":"integer"},"title":{"maxLength":300,"minLength":1,"type":"string"},"type":{"enum":["task"],"type":"string"}},"required":["type","title","dueInDays"],"type":"object"},{"properties":{"durationMinutes":{"maximum":480,"minimum":5,"type":"integer"},"startInDays":{"maximum":365,"minimum":0,"type":"integer"},"title":{"maxLength":300,"minLength":1,"type":"string"},"type":{"enum":["meeting"],"type":"string"}},"required":["type","title","startInDays"],"type":"object"}]},"maxItems":4,"type":"array"},"id":{"maxLength":128,"minLength":1,"type":"string"},"label":{"enum":["interested","ready_to_move","callback_requested","follow_up_needed","objection_raised","not_interested","not_a_fit",null],"nullable":true,"type":"string"},"sentiment":{"enum":["positive","neutral","negative"],"type":"string"},"summary":{"maxLength":4000,"minLength":1,"type":"string"}},"required":["id","label","summary","sentiment","actions"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmCallAnalysisResult"}}},"description":"The call row with the analysis persisted."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Persist an AI analysis of a recorded call","tags":["CRM"]}},"/v1/crm/calls/analyze":{"post":{"operationId":"analyzeCrmCall","requestBody":{"content":{"application/json":{"schema":{"properties":{"contactName":{"maxLength":200,"type":"string"},"id":{"maxLength":128,"minLength":1,"type":"string"}},"required":["id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmCallAnalyzeResult"}}},"description":"The call row with the analysis persisted."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"The call's transcript isn't completed yet."},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"The model didn't return a usable analysis."}},"summary":"Analyze a recorded call's transcript with AI and persist it","tags":["CRM"]}},"/v1/crm/calls/transcript":{"get":{"operationId":"getCrmCallTranscript","parameters":[{"in":"query","name":"id","required":true,"schema":{"minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmCallTranscriptResult"}}},"description":"The call row with the transcript pipeline advanced."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Poll a recorded call's transcript (advances the pipeline)","tags":["CRM"]}},"/v1/crm/contacts":{"delete":{"operationId":"removeCrmContactMethod","requestBody":{"content":{"application/json":{"schema":{"properties":{"id":{"type":"string"}},"required":["id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmRemoveContactResult"}}},"description":"Whether a contact was removed."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Remove a user-added contact method","tags":["CRM"]},"patch":{"operationId":"updateCrmContactMethod","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmPatchContactBody"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmPatchContactResult"}}},"description":"The update flag, or the id of the suppression tombstone."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Update or suppress a contact method","tags":["CRM"]},"post":{"operationId":"addCrmContactMethod","requestBody":{"content":{"application/json":{"schema":{"properties":{"entityId":{"type":"string"},"isPrimary":{"type":"boolean"},"kind":{"$ref":"#/components/schemas/CrmContactKind"},"label":{"nullable":true,"type":"string"},"mmKey":{"nullable":true,"type":"string"},"value":{"nullable":true}},"required":["entityId","kind"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmAddContactResult"}}},"description":"The id of the newly added contact method."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Add a contact method to a record","tags":["CRM"]}},"/v1/crm/custom-values":{"get":{"operationId":"getCrmCustomValues","parameters":[{"in":"query","name":"entityId","required":false,"schema":{"type":"string"}},{"in":"query","name":"entityIds","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmCustomValueResult"}}},"description":"Single: values keyed by field id. Bulk: keyed by entity id then field id."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Get custom-field values for one or many records","tags":["CRM"]},"patch":{"operationId":"setCrmCustomValue","requestBody":{"content":{"application/json":{"schema":{"properties":{"entityId":{"type":"string"},"fieldId":{"type":"string"},"value":{"$ref":"#/components/schemas/CrmCustomValue"}},"required":["entityId","fieldId","value"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmSetCustomValueResult"}}},"description":"Acknowledgement that the value was written."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Set a record's value for one custom field","tags":["CRM"]}},"/v1/crm/email/send":{"post":{"operationId":"sendCrmEmail","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmEmailSendBody"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmEmailSendResult"}}},"description":"Sent, or needs-connect when no send connector is available."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmEmailUpstreamError"}}},"description":"Upstream provider error."}},"summary":"Send an outbound email via the user's connected Gmail or Outlook","tags":["CRM"]}},"/v1/crm/enrich/apply":{"post":{"operationId":"applyCrmEnrichment","requestBody":{"content":{"application/json":{"schema":{"properties":{"contacts":{"items":{"$ref":"#/components/schemas/CrmEnrichmentContact"},"type":"array"},"display":{"$ref":"#/components/schemas/CrmDisplay"},"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"link":{"allOf":[{"$ref":"#/components/schemas/CrmLink"},{"description":"Set to accept the match; omit to leave unlinked."}]},"overrideSources":{"$ref":"#/components/schemas/CrmEnrichmentOverrideSources"},"overrides":{"$ref":"#/components/schemas/CrmEnrichmentOverrides"}},"required":["entityId","entityType"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmEnrichmentResult"}}},"description":"Whether a match was linked + the count of seeded contacts."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Apply a match to an imported record (link + seed contacts)","tags":["CRM"]}},"/v1/crm/fields":{"get":{"operationId":"listCrmCustomFields","parameters":[{"in":"query","name":"objectType","required":true,"schema":{"$ref":"#/components/schemas/CrmObjectType"}},{"description":"Also include this list's list-scoped fields.","in":"query","name":"listId","required":false,"schema":{"description":"Also include this list's list-scoped fields.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmCustomFieldList"}}},"description":"Object-scoped fields plus any requested list-scoped fields."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List custom fields applicable to a view","tags":["CRM"]}},"/v1/crm/import":{"post":{"operationId":"importCrmRecords","requestBody":{"content":{"application/json":{"schema":{"properties":{"entityType":{"allOf":[{"$ref":"#/components/schemas/CrmEntityType"},{"description":"Entity type for created rows (default per object)."}]},"listId":{"nullable":true,"type":"string"},"objectType":{"$ref":"#/components/schemas/CrmObjectType"},"ownerUserId":{"description":"Default working owner (member userId) for created rows; a row's own ownerUserId overrides it. Both fall back to the caller. Assigning an owner other than the caller requires an org admin.","type":"string"},"rows":{"items":{"$ref":"#/components/schemas/CrmImportRow"},"type":"array"}},"required":["objectType","rows"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmImportResult"}}},"description":"Small batch: per-row outcomes plus the batch tally."},"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmImportAccepted"}}},"description":"Large batch accepted for asynchronous processing; returns a job handle."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable (owner-assignment member lookup failed)."}},"summary":"Bulk import records (create or update), optionally into a list","tags":["CRM"]}},"/v1/crm/import/{jobId}":{"get":{"operationId":"getCrmImportJob","parameters":[{"description":"Job id from a 202 import.","in":"path","name":"jobId","required":true,"schema":{"description":"Job id from a 202 import.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmImportJob"}}},"description":"Job status (queued / running / completed / failed)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Get an async import job's status (progress + per-row errors)","tags":["CRM"]}},"/v1/crm/lender-channels":{"post":{"operationId":"crmLenderChannels","requestBody":{"content":{"application/json":{"schema":{"properties":{"loNmlsIds":{"description":"Bare LO NMLS ids (deduped, capped at 500).","items":{"type":"string"},"type":"array"}},"required":["loNmlsIds"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmLenderChannels"}}},"description":"Per-LO current sponsor company + classified lender channel."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Bank / Credit Union / Broker / Retail channel per LO (by NMLS)","tags":["CRM"]}},"/v1/crm/lists":{"get":{"operationId":"listCrmLists","parameters":[{"in":"query","name":"objectType","required":false,"schema":{"$ref":"#/components/schemas/CrmObjectType"}},{"in":"query","name":"entityId","required":false,"schema":{"minLength":1,"type":"string"}},{"in":"query","name":"scope","required":false,"schema":{"enum":["visible","all"],"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmListArray"}}},"description":"Visible lists (own + org-wide + shared-with-me); scope=all returns every workspace list for admins."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List the caller's lists (picker mode with ?entityId adds hasMember)","tags":["CRM"]},"post":{"operationId":"createCrmList","requestBody":{"content":{"application/json":{"schema":{"properties":{"name":{"type":"string"},"objectType":{"$ref":"#/components/schemas/CrmObjectType"}},"required":["name","objectType"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmListCreateResult"}}},"description":"The created list."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Create a list","tags":["CRM"]}},"/v1/crm/lists/memberships":{"get":{"operationId":"listCrmListMemberships","parameters":[{"in":"query","name":"objectType","required":false,"schema":{"$ref":"#/components/schemas/CrmObjectType"}},{"in":"query","name":"entityIds","required":true,"schema":{"minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmListMembershipsResult"}}},"description":"Each requested entityId mapped to the visible lists it's on ([] = none)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Batched list-membership lookup for many entities","tags":["CRM"]}},"/v1/crm/lists/{id}":{"delete":{"operationId":"deleteCrmList","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmListDeleteResult"}}},"description":"Deleted (soft)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Delete a list","tags":["CRM"]},"get":{"operationId":"getCrmList","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmListWithMembers"}}},"description":"The list + members, or null when not found / not visible."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Get a list with its members","tags":["CRM"]},"patch":{"operationId":"updateCrmList","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmListUpdateBody"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmListUpdateResult"}}},"description":"The updated list (null when only a sub-op with no rename ran)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Update a list's name, visibility, or whole-org role","tags":["CRM"]}},"/v1/crm/lists/{id}/assignees":{"get":{"operationId":"listCrmListAssignees","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmListAssigneeList"}}},"description":"Members who can access the list."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"List not found."},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable."}},"summary":"List who can be assigned on a list (access-filtered by visibility)","tags":["CRM"]}},"/v1/crm/lists/{id}/filter-members":{"post":{"operationId":"filterCrmListMembers","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"filter":{"$ref":"#/components/schemas/CrmMemberFilter"},"limit":{"exclusiveMinimum":true,"minimum":0,"type":"integer"}},"required":["filter"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmFilterMembersResult"}}},"description":"Matching member entity ids (resolved in Postgres)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Filter a list's members by entity attributes (read)","tags":["CRM"]}},"/v1/crm/lists/{id}/member-ids":{"get":{"operationId":"getCrmListMemberIds","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmMemberIdsResult"}}},"description":"Every member entity id of the list, all entity types."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List a CRM list's member entity ids (ids only)","tags":["CRM"]}},"/v1/crm/lists/{id}/members":{"delete":{"operationId":"removeCrmListMember","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"entityId":{"type":"string"}},"required":["entityId"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmRemoveListMemberResult"}}},"description":"Whether a membership was removed."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Remove a member from a list","tags":["CRM"]},"post":{"operationId":"addCrmListMember","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"display":{"$ref":"#/components/schemas/CrmDisplay"},"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"grantRecordAccessUserIds":{"items":{"type":"string"},"type":"array"},"link":{"$ref":"#/components/schemas/CrmLink"},"note":{"properties":{"body":{"type":"string"},"bodyHtml":{"nullable":true,"type":"string"}},"required":["body"],"type":"object"},"ownerUserId":{"type":"string"},"status":{"type":"string"}},"required":["entityType","entityId","link","display"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmAddListMemberResult"}}},"description":"Whether the member was newly added + the member row."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Add a member to a list","tags":["CRM"]}},"/v1/crm/lists/{id}/members/bulk":{"post":{"operationId":"addCrmListMembersBulk","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"grantRecordAccessUserIds":{"items":{"type":"string"},"type":"array"},"members":{"items":{"properties":{"company":{"type":"string"},"companyType":{"type":"string"},"contacts":{"items":{"$ref":"#/components/schemas/CrmContactSeed"},"type":"array"},"display":{"$ref":"#/components/schemas/CrmDisplay"},"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"link":{"$ref":"#/components/schemas/CrmLink"},"title":{"type":"string"}},"required":["entityType","entityId","display"],"type":"object"},"minItems":1,"type":"array"},"note":{"properties":{"body":{"type":"string"},"bodyHtml":{"nullable":true,"type":"string"}},"required":["body"],"type":"object"},"ownerUserId":{"type":"string"},"status":{"type":"string"}},"required":["members"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmAddMembersBulkResult"}}},"description":"Counts + the ids newly added."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Add many members to a list","tags":["CRM"]}},"/v1/crm/lists/{id}/shareable-members":{"get":{"operationId":"listCrmListShareableMembers","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmShareableMemberList"}}},"description":"The org roster for the list's sharing picker (all members)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable."}},"summary":"List the org members a list can be shared with (manage-gated)","tags":["CRM"]}},"/v1/crm/lists/{id}/shares":{"delete":{"operationId":"revokeCrmListAccess","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"userId":{"type":"string"}},"required":["userId"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmRevokeListAccessResult"}}},"description":"Whether a grant was removed."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Revoke a member's access to a list","tags":["CRM"]},"get":{"operationId":"getCrmListShares","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmListSharingResult"}}},"description":"Visibility + owner display + enriched grants, or null."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable."}},"summary":"Get a list's sharing state (+ owner display, canManageSharing)","tags":["CRM"]},"patch":{"operationId":"transferCrmListOwnership","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"newOwnerUserId":{"type":"string"}},"required":["newOwnerUserId"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmTransferListOwnershipResult"}}},"description":"Whether ownership moved (false when the target is already the owner)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Transfer a list's ownership to another member","tags":["CRM"]},"post":{"operationId":"grantCrmListAccess","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"permission":{"enum":["editor","viewer"],"type":"string"},"userId":{"type":"string"}},"required":["userId"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmGrantListAccessResult"}}},"description":"Whether a new grant was created."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Grant a member access to a list","tags":["CRM"]}},"/v1/crm/lists/{listId}/apply-template":{"post":{"operationId":"applyCrmListTemplate","parameters":[{"in":"path","name":"listId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmApplyTemplateBody"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmApplyTemplateResult"}}},"description":"Fields that landed vs. were skipped (additive, idempotent)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Replay a template's fields onto a list","tags":["CRM"]}},"/v1/crm/lists/{listId}/fields":{"delete":{"operationId":"deleteCrmListField","parameters":[{"in":"path","name":"listId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"id":{"type":"string"}},"required":["id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmDeleteListFieldResult"}}},"description":"Whether the field was deleted."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Delete a custom field","tags":["CRM"]},"get":{"operationId":"listCrmListFields","parameters":[{"in":"path","name":"listId","required":true,"schema":{"type":"string"}},{"in":"query","name":"objectType","required":false,"schema":{"$ref":"#/components/schemas/CrmObjectType"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmListFieldsResult"}}},"description":"Object-scoped fields plus this list's list-scoped fields."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List the custom fields applicable to a list","tags":["CRM"]},"patch":{"operationId":"updateCrmListField","parameters":[{"in":"path","name":"listId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"config":{"additionalProperties":{"nullable":true},"nullable":true,"type":"object"},"id":{"type":"string"},"label":{"type":"string"},"options":{"items":{"$ref":"#/components/schemas/CrmCustomFieldOption"},"nullable":true,"type":"array"},"sortOrder":{"type":"number"}},"required":["id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmUpdateListFieldResult"}}},"description":"Whether the field was updated."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Update a custom field's mutable props","tags":["CRM"]},"post":{"operationId":"createCrmListField","parameters":[{"in":"path","name":"listId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"config":{"additionalProperties":{"nullable":true},"nullable":true,"type":"object"},"key":{"type":"string"},"label":{"type":"string"},"objectType":{"$ref":"#/components/schemas/CrmObjectType"},"options":{"items":{"$ref":"#/components/schemas/CrmCustomFieldOption"},"nullable":true,"type":"array"},"sortOrder":{"type":"number"},"type":{"$ref":"#/components/schemas/CrmCustomFieldType"}},"required":["label","type"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmCreateListFieldResult"}}},"description":"The created custom field."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Create a list-scoped custom field","tags":["CRM"]}},"/v1/crm/lo-loan-mix":{"post":{"operationId":"crmLoLoanMix","requestBody":{"content":{"application/json":{"schema":{"properties":{"dateRange":{"description":"Period key (default: last_14_months).","type":"string"},"nmls":{"description":"Bare NMLS id.","type":"string"}},"required":["nmls"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmLoLoanMix"}}},"description":"Loan-type percentage breakdown + the top loan type (or null)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Loan-type mix (percentage + top type) for a single LO (by NMLS)","tags":["CRM"]}},"/v1/crm/lo-momentum":{"post":{"operationId":"crmLoMomentum","requestBody":{"content":{"application/json":{"schema":{"properties":{"nmls":{"description":"Bare NMLS ids (deduped, capped at 50).","items":{"type":"string"},"type":"array"}},"required":["nmls"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmLoMomentum"}}},"description":"Per-NMLS recent (last 3mo) vs prior (3mo) closed-loan units."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Recent-vs-prior 3-month closed-loan units for a set of LOs (by NMLS)","tags":["CRM"]}},"/v1/crm/lo-sponsor-location":{"post":{"operationId":"crmLoSponsorLocation","requestBody":{"content":{"application/json":{"schema":{"properties":{"nmlsIds":{"description":"Bare NMLS ids (deduped, empties dropped, capped 2000).","items":{"type":"string"},"type":"array"}},"required":["nmlsIds"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmLoSponsorLocation"}}},"description":"Per-NMLS current-sponsor office location (optional) + sponsored flag. Ids not on file are omitted."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Current-sponsor office location + sponsored flag for a set of LOs","tags":["CRM"]}},"/v1/crm/match":{"patch":{"operationId":"linkCrmRecord","requestBody":{"content":{"application/json":{"schema":{"properties":{"display":{"$ref":"#/components/schemas/CrmDisplay"},"entityId":{"type":"string"},"link":{"$ref":"#/components/schemas/CrmLink"}},"required":["entityId","link"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmLinkRecordResult"}}},"description":"Whether the record was linked."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Link a record to a chosen candidate","tags":["CRM"]},"post":{"operationId":"searchCrmMatchCandidates","requestBody":{"content":{"application/json":{"schema":{"properties":{"city":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"name":{"minLength":1,"type":"string"},"state":{"type":"string"}},"required":["entityType","name"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmMatchCandidates"}}},"description":"Ranked candidates (best first)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Find candidate entities to link an unmatched record to","tags":["CRM"]}},"/v1/crm/meetings":{"delete":{"operationId":"deleteCrmMeeting","parameters":[{"in":"query","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmMeetingDeleted"}}},"description":"Success."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Delete a meeting (and its provider event)","tags":["CRM"]},"get":{"operationId":"listCrmMeetings","parameters":[{"in":"query","name":"entityId","required":true,"schema":{"type":"string"}},{"in":"query","name":"status","required":false,"schema":{"$ref":"#/components/schemas/CrmMeetingStatus"}},{"in":"query","name":"upcoming","required":false,"schema":{"enum":["0","1"],"type":"string"}},{"in":"query","name":"reconcile","required":false,"schema":{"enum":["0","1"],"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmMeetingList"}}},"description":"Success."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List meetings for a record","tags":["CRM"]},"patch":{"operationId":"updateCrmMeeting","requestBody":{"content":{"application/json":{"schema":{"properties":{"action":{"enum":["update","cancel","complete","sync"],"type":"string"},"description":{"nullable":true,"type":"string"},"endAt":{"type":"number"},"id":{"type":"string"},"inviteeEmail":{"nullable":true,"type":"string"},"inviteeName":{"nullable":true,"type":"string"},"location":{"nullable":true,"type":"string"},"provider":{"$ref":"#/components/schemas/CrmMeetingProvider"},"recordName":{"type":"string"},"recordUrl":{"type":"string"},"startAt":{"type":"number"},"teammateUserIds":{"items":{"type":"string"},"type":"array"},"timezone":{"nullable":true,"type":"string"},"title":{"type":"string"}},"required":["id","action"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmMeetingUpdated"}}},"description":"Success."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Update, cancel, complete, or re-sync a meeting","tags":["CRM"]},"post":{"operationId":"createCrmMeeting","requestBody":{"content":{"application/json":{"schema":{"properties":{"description":{"nullable":true,"type":"string"},"endAt":{"type":"number"},"entityId":{"type":"string"},"inviteeEmail":{"nullable":true,"type":"string"},"inviteeName":{"nullable":true,"type":"string"},"listId":{"maxLength":128,"minLength":1,"type":"string"},"location":{"nullable":true,"type":"string"},"provider":{"$ref":"#/components/schemas/CrmMeetingProvider"},"recordName":{"type":"string"},"recordUrl":{"type":"string"},"startAt":{"type":"number"},"teammateUserIds":{"items":{"type":"string"},"type":"array"},"timezone":{"nullable":true,"type":"string"},"title":{"minLength":1,"type":"string"}},"required":["entityId","title","startAt","endAt"],"type":"object"}}}},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmMeetingCreated"}}},"description":"Created."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Create a meeting (optionally syncing it to a calendar provider)","tags":["CRM"]}},"/v1/crm/meetings/reconcile":{"post":{"operationId":"reconcileCrmMeetings","requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"properties":{"entityId":{"type":"string"}},"required":["entityId"],"type":"object"},{"properties":{"scope":{"enum":["user"],"type":"string"}},"required":["scope"],"type":"object"}]}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmMeetingReconcileResult"}}},"description":"Success."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Pull calendar changes and apply them (one record, or user-wide)","tags":["CRM"]}},"/v1/crm/meetings/workspace":{"get":{"operationId":"listCrmWorkspaceMeetings","parameters":[{"in":"query","name":"status","required":false,"schema":{"$ref":"#/components/schemas/CrmMeetingStatus"}},{"description":"Restrict to one organizer; omit for anyone on my records.","in":"query","name":"organizer","required":false,"schema":{"description":"Restrict to one organizer; omit for anyone on my records.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmWorkspaceMeetingList"}}},"description":"Meetings on visible records, soonest first."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Cross-record meeting inbox for the caller's visible records","tags":["CRM"]}},"/v1/crm/members":{"get":{"operationId":"listCrmMembers","parameters":[{"in":"query","name":"objectType","required":true,"schema":{"$ref":"#/components/schemas/CrmObjectType"}},{"description":"`me` scopes to the caller's records; omit for everyone.","in":"query","name":"owner","required":false,"schema":{"description":"`me` scopes to the caller's records; omit for everyone.","enum":["me"],"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmMembersList"}}},"description":"The visible records of the object type, newest first."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List curated CRM records of an object type","tags":["CRM"]}},"/v1/crm/org-members":{"get":{"operationId":"listCrmOrgMembers","parameters":[{"in":"query","name":"search","required":false,"schema":{"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"exclusiveMinimum":true,"minimum":0,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmOrgMemberList"}}},"description":"The active org's members (optionally searched)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable."}},"summary":"List the active org's members","tags":["CRM"]}},"/v1/crm/overrides":{"get":{"operationId":"getCrmOverrides","parameters":[{"description":"Comma-separated record ids.","in":"query","name":"entityIds","required":true,"schema":{"description":"Comma-separated record ids.","example":"lo:1,lo:2","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmOverridesMap"}}},"description":"The overlay per entity id."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Batch-read record overrides","tags":["CRM"]},"patch":{"operationId":"setCrmOverride","requestBody":{"content":{"application/json":{"schema":{"properties":{"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"field":{"$ref":"#/components/schemas/CrmOverrideField"},"value":{"anyOf":[{"type":"string"},{"$ref":"#/components/schemas/CrmOverrideOffice"}]}},"required":["entityId","entityType","field","value"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmSetOverrideResult"}}},"description":"The record's updated overlay (+ re-derived location facets)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Set a single override field on a record","tags":["CRM"]}},"/v1/crm/production-enrich/{jobId}":{"get":{"operationId":"getCrmProductionEnrichJob","parameters":[{"description":"Job id from a bulk/import add.","in":"path","name":"jobId","required":true,"schema":{"description":"Job id from a bulk/import add.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmProductionEnrichJob"}}},"description":"Job status (queued / running / completed / failed)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Get an add-time production-enrich job's status","tags":["CRM"]}},"/v1/crm/profile":{"get":{"operationId":"getCrmRecordProfile","parameters":[{"description":"The CRM record id to read.","in":"query","name":"entityId","required":true,"schema":{"description":"The CRM record id to read.","minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmProfile"}}},"description":"The record's aggregate profile payload."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Aggregate profile read for a CRM record","tags":["CRM"]}},"/v1/crm/recipients":{"get":{"operationId":"searchCrmEmailRecipients","parameters":[{"description":"Name or address fragment.","in":"query","name":"q","required":true,"schema":{"description":"Name or address fragment.","type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"exclusiveMinimum":true,"minimum":0,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmEmailRecipientArray"}}},"description":"Matching records with a stored email address."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Typeahead search for email recipients the caller can see","tags":["CRM"]}},"/v1/crm/record-access":{"get":{"operationId":"getCrmRecordAccess","parameters":[{"description":"The record's entity id.","in":"query","name":"entityId","required":true,"schema":{"description":"The record's entity id.","minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmRecordAccessFacts"}}},"description":"The resolved accessible-user set + the caller's manage capability."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Record not found / not accessible to the caller."},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable."}},"summary":"Who can access a record, and whether the caller may manage shares","tags":["CRM"]}},"/v1/crm/record-shareable-members":{"get":{"operationId":"listCrmRecordShareableMembers","parameters":[{"description":"The record's entity id.","in":"query","name":"entityId","required":true,"schema":{"description":"The record's entity id.","minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmRecordShareableMemberList"}}},"description":"The org roster for the record's share picker (all members)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable."}},"summary":"List the org members a record can be shared with (manage-gated)","tags":["CRM"]}},"/v1/crm/record-shares":{"delete":{"operationId":"revokeCrmRecordAccess","requestBody":{"content":{"application/json":{"schema":{"properties":{"entityId":{"type":"string"},"userId":{"type":"string"}},"required":["entityId","userId"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmRevokeRecordAccessResult"}}},"description":"Whether a share was removed."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable (roster needed for the gate)."}},"summary":"Revoke a user's access to a record","tags":["CRM"]},"get":{"operationId":"listCrmRecordShares","parameters":[{"description":"The record's entity id.","in":"query","name":"entityId","required":true,"schema":{"description":"The record's entity id.","minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmRecordShareList"}}},"description":"The per-user share grants on the record, with display."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable."}},"summary":"List the direct shares on a record (+ display, canManageShares)","tags":["CRM"]},"post":{"operationId":"grantCrmRecordAccess","requestBody":{"content":{"application/json":{"schema":{"properties":{"entityId":{"type":"string"},"listId":{"type":"string"},"source":{"enum":["mention","manual"],"type":"string"},"userId":{"type":"string"}},"required":["entityId","userId"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmGrantRecordAccessResult"}}},"description":"Whether a new share was created (idempotent)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable (roster needed for the gate)."}},"summary":"Grant a user access to a record","tags":["CRM"]}},"/v1/crm/records":{"delete":{"operationId":"deleteCrmRecord","parameters":[{"description":"The record id.","in":"query","name":"entityId","required":true,"schema":{"description":"The record id.","minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmDeleteRecordResult"}}},"description":"Whether a record was removed."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Remove a record from the workspace CRM","tags":["CRM"]},"patch":{"operationId":"setCrmRecordOwner","requestBody":{"content":{"application/json":{"schema":{"properties":{"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"grantAccess":{"type":"boolean"},"ownerUserId":{"nullable":true,"type":"string"}},"required":["entityId","entityType","ownerUserId"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmSetOwnerResult"}}},"description":"The record's owner after the call; `needsShare` is set instead when the assignee can't see the record and the write was held."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"(Re)assign a record's working owner","tags":["CRM"]},"post":{"operationId":"createCrmRecord","requestBody":{"content":{"application/json":{"schema":{"properties":{"display":{"$ref":"#/components/schemas/CrmDisplay"},"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"link":{"$ref":"#/components/schemas/CrmLink"},"ownerUserId":{"type":"string"}},"required":["entityId","entityType","link","display"],"type":"object"}}}},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmCreateRecordResult"}}},"description":"Whether the record was newly created (vs. refreshed)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Create (or refresh) a canonical record from a match","tags":["CRM"]}},"/v1/crm/records/access-request":{"get":{"operationId":"getCrmRecordAccessRequest","parameters":[{"in":"query","name":"requestId","required":true,"schema":{"minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmRecordAccessRequestInfo"}}},"description":"The pending ask, for the confirm prompt."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable (roster needed for the gate)."}},"summary":"Resolve a record access request for the owner's grant-confirm screen","tags":["CRM"]}},"/v1/crm/records/add":{"post":{"operationId":"addCrmRecord","requestBody":{"content":{"application/json":{"schema":{"properties":{"display":{"$ref":"#/components/schemas/CrmDisplay"},"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"grantRecordAccessUserIds":{"items":{"type":"string"},"type":"array"},"link":{"$ref":"#/components/schemas/CrmLink"},"listId":{"type":"string"},"note":{"properties":{"body":{"type":"string"},"bodyHtml":{"nullable":true,"type":"string"}},"required":["body"],"type":"object"},"ownerUserId":{"type":"string"},"status":{"type":"string"}},"required":["entityType","entityId","link","display"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmAddRecordResult"}}},"description":"Whether the record was newly added + the member row."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Add a record to the CRM (and optionally a list)","tags":["CRM"]}},"/v1/crm/records/add/bulk":{"post":{"operationId":"addCrmRecordsBulk","requestBody":{"content":{"application/json":{"schema":{"properties":{"grantRecordAccessUserIds":{"items":{"type":"string"},"type":"array"},"members":{"items":{"properties":{"company":{"type":"string"},"companyType":{"type":"string"},"display":{"$ref":"#/components/schemas/CrmDisplay"},"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"link":{"$ref":"#/components/schemas/CrmLink"},"title":{"type":"string"}},"required":["entityType","entityId","link","display"],"type":"object"},"minItems":1,"type":"array"},"note":{"properties":{"body":{"type":"string"},"bodyHtml":{"nullable":true,"type":"string"}},"required":["body"],"type":"object"},"ownerUserId":{"type":"string"},"status":{"type":"string"}},"required":["members"],"type":"object"}}}},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmAddRecordsBulkResult"}}},"description":"Counts + the ids newly added."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Bulk add records to the canonical CRM (listless)","tags":["CRM"]}},"/v1/crm/records/apply-mi-updates":{"post":{"operationId":"applyCrmMiUpdates","requestBody":{"content":{"application/json":{"schema":{"properties":{"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"updates":{"items":{"oneOf":[{"properties":{"field":{"enum":["title","company","location","city","state","zip"],"type":"string"},"store":{"enum":["override"],"type":"string"},"value":{"maxLength":2000,"minLength":1,"type":"string"}},"required":["store","field","value"],"type":"object"},{"properties":{"kind":{"enum":["email","phone","linkedin","facebook","x","instagram","youtube","zillow","realtor","website"],"type":"string"},"store":{"enum":["contact"],"type":"string"},"value":{"maxLength":2000,"minLength":1,"type":"string"}},"required":["store","kind","value"],"type":"object"}]},"minItems":1,"type":"array"}},"required":["entityId","entityType","updates"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmApplyMiUpdatesResult"}}},"description":"How many accepted fields were persisted."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Apply the Market-Insights updates the user accepted","tags":["CRM"]}},"/v1/crm/records/by-nmls":{"get":{"operationId":"findCrmRecordByNmls","parameters":[{"description":"Bare NMLS id.","in":"query","name":"nmlsId","required":true,"schema":{"description":"Bare NMLS id.","minLength":1,"type":"string"}},{"description":"Comma-separated entity types to match (default: all).","in":"query","name":"entityTypes","required":false,"schema":{"description":"Comma-separated entity types to match (default: all).","example":"lo,company","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmRecordRef"}}},"description":"The matching record ref, or null when none exists."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Find an existing CRM record by NMLS id","tags":["CRM"]}},"/v1/crm/records/connections":{"post":{"operationId":"getCrmRecordConnections","requestBody":{"content":{"application/json":{"schema":{"properties":{"branchName":{"type":"string"},"branchNmlsId":{"type":"string"},"companyName":{"type":"string"},"companyNmlsId":{"type":"string"},"entityId":{"minLength":1,"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"officeKey":{"type":"string"},"officeName":{"type":"string"},"partnerEntityIds":{"items":{"type":"string"},"type":"array"}},"required":["entityId","entityType"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmRecordConnections"}}},"description":"In-CRM partner ids + colleagues tagged with their list names."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Relationship cross-reference for a record (in-CRM partners + colleagues)","tags":["CRM"]}},"/v1/crm/records/create":{"post":{"operationId":"createCrmManualRecord","requestBody":{"content":{"application/json":{"schema":{"properties":{"contacts":{"items":{"$ref":"#/components/schemas/CrmContactSeed"},"maxItems":30,"type":"array"},"customValues":{"additionalProperties":{"$ref":"#/components/schemas/CrmCustomValue"},"type":"object"},"display":{"$ref":"#/components/schemas/CrmDisplay"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"listId":{"type":"string"},"overrides":{"properties":{"city":{"type":"string"},"company":{"type":"string"},"companyNmlsId":{"type":"string"},"companyType":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"location":{"type":"string"},"notes":{"type":"string"},"office":{"type":"string"},"state":{"type":"string"},"status":{"type":"string"},"title":{"type":"string"},"zip":{"type":"string"}},"type":"object"},"ownerUserId":{"type":"string"}},"required":["entityType","display"],"type":"object"}}}},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmManualRecordResult"}}},"description":"The new record's id + whether it joined the given list."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Create a manual (unmatched) CRM record","tags":["CRM"]}},"/v1/crm/records/delete":{"post":{"operationId":"deleteCrmRecords","requestBody":{"content":{"application/json":{"schema":{"properties":{"entityIds":{"items":{"type":"string"},"minItems":1,"type":"array"}},"required":["entityIds"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmDeleteRecordsResult"}}},"description":"Ids actually removed vs. skipped (not owned / not found)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Remove one or more records from the CRM","tags":["CRM"]}},"/v1/crm/records/describe-on-add":{"post":{"operationId":"describeCrmRecordsOnAdd","requestBody":{"content":{"application/json":{"schema":{"properties":{"created":{"items":{"properties":{"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"}},"required":["entityId","entityType"],"type":"object"},"maxItems":500,"minItems":1,"type":"array"}},"required":["created"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmDescribeOnAddResult"}}},"description":"The created entity ids that need a generate-description run (cache misses this caller claimed)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Resolve descriptions for just-created records (cache-first)","tags":["CRM"]}},"/v1/crm/records/dismiss-mi-updates":{"post":{"operationId":"dismissCrmMiUpdates","requestBody":{"content":{"application/json":{"schema":{"properties":{"entityId":{"type":"string"},"seen":{"additionalProperties":{"items":{"maxLength":512,"type":"string"},"maxItems":50,"type":"array"},"type":"object"}},"required":["entityId"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmDismissMiUpdatesResult"}}},"description":"Confirmation the check window was restarted. The seen-ledger is untouched."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Snooze surfaced MI updates for the check window","tags":["CRM"]}},"/v1/crm/records/generate-description":{"post":{"operationId":"generateCrmRecordDescription","requestBody":{"content":{"application/json":{"schema":{"properties":{"company":{"type":"string"},"entityId":{"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"},"location":{"type":"string"},"name":{"type":"string"},"title":{"type":"string"}},"required":["entityId","entityType"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmGenerateDescriptionResult"}}},"description":"The generated description, or null when no usable source was found."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Auto-generate a record's description from the web","tags":["CRM"]}},"/v1/crm/records/grant-access":{"post":{"operationId":"grantCrmRecordAccessRequest","requestBody":{"content":{"application/json":{"schema":{"properties":{"requestId":{"minLength":1,"type":"string"}},"required":["requestId"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmGrantRecordAccessRequestResult"}}},"description":"The requester was granted access (idempotent) and the ask closed."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable (roster needed for the gate)."}},"summary":"Grant a pending record access request (owner/admin, one tap)","tags":["CRM"]}},"/v1/crm/records/member-ids":{"get":{"operationId":"getCrmRecordMemberIds","parameters":[{"in":"query","name":"objectType","required":true,"schema":{"$ref":"#/components/schemas/CrmObjectType"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmMemberIdsResult"}}},"description":"Every workspace record id of the object type."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List the workspace's record entity ids of an object type (ids only)","tags":["CRM"]}},"/v1/crm/records/mention-search":{"post":{"operationId":"searchCrmMentionRecords","requestBody":{"content":{"application/json":{"schema":{"properties":{"q":{"default":"","type":"string"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmMentionSearch"}}},"description":"The viewer-visible records matching the query (or recent)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Name-first search over visible CRM records for the mention picker","tags":["CRM"]}},"/v1/crm/records/mi-updates":{"post":{"operationId":"getCrmMiUpdates","requestBody":{"content":{"application/json":{"schema":{"properties":{"entityId":{"maxLength":128,"minLength":1,"type":"string"},"entityType":{"$ref":"#/components/schemas/CrmEntityType"}},"required":["entityId","entityType"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmMiUpdatesResult"}}},"description":"The available per-field updates + the check timestamp (null when skipped)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Compute which Market-Insights fields differ from a record snapshot","tags":["CRM"]}},"/v1/crm/records/request-access":{"post":{"operationId":"requestCrmRecordAccess","requestBody":{"content":{"application/json":{"schema":{"properties":{"entityId":{"minLength":1,"type":"string"},"organizationId":{"minLength":1,"type":"string"}},"required":["organizationId","entityId"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmRecordRequestAccessResult"}}},"description":"The owner was emailed, a recent request still stands, or the caller already has access."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"The record has no owner/admin to notify."},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Owner-roster lookup or email send failed — safe to retry."}},"summary":"Ask a record's owner to share it (membership-gated, notify-only)","tags":["CRM"]}},"/v1/crm/records/search":{"post":{"operationId":"searchCrmRecords","requestBody":{"content":{"application/json":{"schema":{"properties":{"listId":{"description":"Scope to one list's members; omit for the full CRM.","type":"string"},"objectType":{"$ref":"#/components/schemas/CrmObjectType"},"q":{"description":"Free-text query.","type":"string"}},"required":["objectType","q"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmRecordSearchResult"}}},"description":"The matching namespaced entity ids."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Free-text search over CRM records","tags":["CRM"]}},"/v1/crm/request-access":{"post":{"operationId":"requestCrmAccess","requestBody":{"content":{"application/json":{"schema":{"properties":{"organizationId":{"minLength":1,"type":"string"}},"required":["organizationId"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmRequestAccessResult"}}},"description":"The owner(s) were emailed, or a recent request still stands."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"The org has no billing owner to notify."},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Owner-roster lookup or email send failed — safe to retry."}},"summary":"Ask the org owner(s) to enable the CRM (membership-gated)","tags":["CRM"]}},"/v1/crm/similar-originators":{"post":{"operationId":"crmSimilarOriginators","requestBody":{"content":{"application/json":{"schema":{"properties":{"dateRange":{"description":"Period key (default: last_14_months).","type":"string"},"partnerNmlsIds":{"description":"Partner LO NMLS ids to rank (deduped, self-excluded, capped at 200).","items":{"type":"string"},"type":"array"},"top":{"description":"Max scored rows to return (1–50, default 25).","type":"number"},"viewerNmls":{"description":"The viewing LO's bare NMLS id.","type":"string"},"weights":{"description":"Live tuning overrides for the tx/loan/size blend (clamped to ≥ 0).","properties":{"loan":{"type":"number"},"size":{"type":"number"},"tx":{"type":"number"}},"type":"object"}},"required":["viewerNmls","partnerNmlsIds"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmSimilarOriginators"}}},"description":"Scored + sorted partner LOs (score, per-component similarity, shared highlight)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Rank an agent's LO partners by product-mix + size similarity to a viewing LO","tags":["CRM"]}},"/v1/crm/tasks":{"delete":{"operationId":"deleteCrmTask","requestBody":{"content":{"application/json":{"schema":{"properties":{"id":{"type":"string"}},"required":["id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmTaskDeleted"}}},"description":"Success."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Delete a task","tags":["CRM"]},"get":{"operationId":"listCrmTasks","parameters":[{"in":"query","name":"entityId","required":false,"schema":{"type":"string"}},{"in":"query","name":"assigneeUserId","required":false,"schema":{"type":"string"}},{"in":"query","name":"owner","required":false,"schema":{"enum":["me"],"type":"string"}},{"in":"query","name":"status","required":false,"schema":{"$ref":"#/components/schemas/CrmTaskStatus"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmTaskList"}}},"description":"Success."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"List tasks for a record or for an assignee","tags":["CRM"]},"patch":{"operationId":"updateCrmTask","requestBody":{"content":{"application/json":{"schema":{"properties":{"action":{"enum":["calendar"],"type":"string"},"allDay":{"type":"boolean"},"assigneeUserId":{"type":"string"},"body":{"nullable":true,"type":"string"},"dueAt":{"nullable":true,"type":"number"},"grantAccess":{"type":"boolean"},"id":{"type":"string"},"provider":{"enum":["google","microsoft",null],"nullable":true,"type":"string"},"recordName":{"type":"string"},"recordUrl":{"type":"string"},"status":{"enum":["completed","cancelled"],"type":"string"},"title":{"type":"string"}},"required":["id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmTaskUpdated"}}},"description":"Success."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Edit a task, or transition it to completed/cancelled","tags":["CRM"]},"post":{"operationId":"createCrmTask","requestBody":{"content":{"application/json":{"schema":{"properties":{"allDay":{"type":"boolean"},"assigneeUserId":{"type":"string"},"body":{"nullable":true,"type":"string"},"dueAt":{"nullable":true,"type":"number"},"entityId":{"type":"string"},"grantAccess":{"type":"boolean"},"listId":{"maxLength":128,"minLength":1,"type":"string"},"title":{"minLength":1,"type":"string"}},"required":["entityId","title"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmTaskCreated"}}},"description":"Success."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Create a task on a record","tags":["CRM"]}},"/v1/crm/tasks/workspace":{"get":{"operationId":"listCrmWorkspaceTasks","parameters":[{"in":"query","name":"status","required":false,"schema":{"$ref":"#/components/schemas/CrmTaskStatus"}},{"description":"Restrict to one assignee; omit for anyone on my records.","in":"query","name":"assignee","required":false,"schema":{"description":"Restrict to one assignee; omit for anyone on my records.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmWorkspaceTaskList"}}},"description":"Tasks on visible records, due-soonest first."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Cross-record task inbox for the caller's visible records","tags":["CRM"]}},"/v1/crm/templates":{"get":{"operationId":"listCrmTemplates","parameters":[{"in":"query","name":"objectType","required":false,"schema":{"$ref":"#/components/schemas/CrmObjectType"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmTemplateList"}}},"description":"Templates owned by or shared with the caller (+ owner display)."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable."}},"summary":"List attribute templates the caller can load","tags":["CRM"]},"post":{"operationId":"createCrmTemplate","requestBody":{"content":{"application/json":{"schema":{"properties":{"fields":{"items":{"properties":{"config":{"additionalProperties":{"nullable":true},"nullable":true,"type":"object"},"key":{"type":"string"},"label":{"type":"string"},"options":{"items":{"properties":{"color":{"type":"string"},"id":{"type":"string"},"label":{"type":"string"}},"required":["id","label"],"type":"object"},"nullable":true,"type":"array"},"sortOrder":{"type":"number"},"type":{"enum":["text","number","currency","date","select","multiselect","url","rating","checkbox","status","tags"],"type":"string"}},"required":["key","label","type"],"type":"object"},"type":"array"},"fromListId":{"type":"string"},"name":{"type":"string"},"objectType":{"$ref":"#/components/schemas/CrmObjectType"}},"required":["name"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmCreateTemplateResult"}}},"description":"The created template with its captured fields."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Create a template (optionally captured from a list)","tags":["CRM"]}},"/v1/crm/templates/{id}":{"delete":{"operationId":"deleteCrmTemplate","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmDeleteTemplateResult"}}},"description":"Whether the template row was deleted."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Delete a template (its fields + shares cascade)","tags":["CRM"]},"get":{"operationId":"getCrmTemplate","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmTemplate"}}},"description":"The template, or null when missing / not accessible."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Load one template with its fields","tags":["CRM"]},"patch":{"operationId":"updateCrmTemplate","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"name":{"type":"string"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmUpdateTemplateResult"}}},"description":"Whether the template row was updated."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Rename a template","tags":["CRM"]}},"/v1/crm/templates/{id}/shares":{"delete":{"operationId":"unshareCrmTemplate","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"userId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmUnshareTemplateResult"}}},"description":"Whether a grant was removed."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Revoke a teammate's template grant","tags":["CRM"]},"get":{"operationId":"getCrmTemplateShares","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmTemplateShareList"}}},"description":"Owner display + caller canManage + enriched grantees."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Template not found / not accessible to the caller."},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Auth service unavailable."}},"summary":"A template's share panel (owner display, canManage, grantees)","tags":["CRM"]},"post":{"operationId":"shareCrmTemplate","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"userId":{"type":"string"}},"required":["userId"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmShareTemplateResult"}}},"description":"Whether a new grant was created."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Grant a teammate load access to a template","tags":["CRM"]}},"/v1/instant-search":{"post":{"description":"Fast typeahead/autocomplete search across agents, originators, companies, and offices. Returns top matches per entity type. A bare NMLS ID resolves directly to its originator, company, or branch. Use this for quick name lookups, not for filtered searches (use the entity-specific list endpoints for those). If you already have an entity ID, prefer getOriginator / getCompany / getBranch.","operationId":"instantSearch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstantSearchRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstantSearchResponse"}}},"description":"Search results grouped by entity"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeiliUnavailable"}}},"description":"Search backend not configured"}},"summary":"Instant multi-entity typeahead search","tags":["Search"]}},"/v1/integrations/hubspot/push":{"post":{"description":"Sends the given Model Match records into the HubSpot account you have connected, using the field mapping your workspace configured. Existing records are matched and updated rather than duplicated, so sending the same list twice does not create it twice. Every id you send comes back with an outcome — some records failing is normal and does not fail the rest. At most 100 records per request; send larger lists in batches. There is no undo: use `dryRun` first to see exactly what would be written. Charged per record actually written, at the same rate as fetching that record.","operationId":"pushToHubspot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HubspotPushRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HubspotPushResponse"}}},"description":"Per-record outcome. Check `summary` for what landed."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HubspotError"}}},"description":"Validation or setup mismatch"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HubspotPaymentRequired"}}},"description":"Not enough credits to send this many records"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"No active workspace"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HubspotError"}}},"description":"Refused before writing anything — not connected, wrong HubSpot account, or a mapping that cannot be applied safely"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HubspotError"}}},"description":"HubSpot or billing could not be reached. Nothing was sent."}},"summary":"Send records to your HubSpot account","tags":["Integrations"]}},"/v1/integrations/hubspot/status":{"get":{"description":"Reports whether your HubSpot account is connected, which record types your workspace has set up to send, and whether the connected account is the one that setup was built for. Read-only — call it before offering to send anything.","operationId":"getHubspotPushStatus","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HubspotStatusResponse"}}},"description":"Readiness per record type"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Check whether records can be sent to HubSpot","tags":["Integrations"]}},"/v1/lenders":{"post":{"description":"Search and list normalized lender names/identities with filters — resolves raw or variant lender names to canonical lender records. Use it to look up a lender by name or reconcile lender-name variants to a single canonical entity. If you only need how many lenders match and not the records themselves, send the same request body to `countLenders`.","operationId":"listLenders","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LenderListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LenderListResponse"}}},"description":"Paginated list of lenders"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Search lenders with filters","tags":["Lenders"]}},"/v1/lenders/count":{"post":{"description":"Return the exact number of lenders matching the given filters. Accepts the same request body as `listLenders` (pagination and sort are ignored). Use this when you only need a total; to get the matching lenders themselves, send the same request body to `listLenders`.","operationId":"countLenders","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LenderListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountResponse"}}},"description":"Exact count of matching lenders"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Count lenders matching filters","tags":["Lenders"],"x-mm-records-via":"listLenders"}},"/v1/lenders/{id}":{"get":{"operationId":"getLender","parameters":[{"description":"Lender canonical-name ID","in":"path","name":"id","required":true,"schema":{"description":"Lender canonical-name ID","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LenderDetailResponse"}}},"description":"Lender detail"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Lender not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large"}},"summary":"Get lender by ID","tags":["Lenders"]}},"/v1/lenders/{id}/breakdowns/cities":{"post":{"description":"Ranks the cities this lender's loans were secured in, by volume. Labels are Title Case so they match the city breakdowns on every other entity.","operationId":"lenderCities","parameters":[{"description":"Lender canonical-name ID","in":"path","name":"id","required":true,"schema":{"description":"Lender canonical-name ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of this lender's loans by cities"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"City volume breakdown across this lender's loans","tags":["Lenders"]}},"/v1/lenders/{id}/breakdowns/companies":{"post":{"description":"Ranks the mortgage companies whose loans funded through this lender, by volume. Each label is the company's NMLS ID (with the company name resolved alongside it where available), so it chains straight into `GET /v1/companies/{nmlsId}`. Loans with no identified company are excluded.","operationId":"lenderCompanies","parameters":[{"description":"Lender canonical-name ID","in":"path","name":"id","required":true,"schema":{"description":"Lender canonical-name ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of this lender's loans by companies"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Mortgage companies that send business to this lender","tags":["Lenders"]}},"/v1/lenders/{id}/breakdowns/counties":{"post":{"description":"Ranks the counties this lender's loans were secured in, by volume. Labels are county codes on this surface — the same axis every other county breakdown uses, so the two are directly comparable.","operationId":"lenderCounties","parameters":[{"description":"Lender canonical-name ID","in":"path","name":"id","required":true,"schema":{"description":"Lender canonical-name ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of this lender's loans by counties"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"County volume breakdown across this lender's loans","tags":["Lenders"]}},"/v1/lenders/{id}/breakdowns/originators":{"post":{"description":"Ranks the loan officers whose loans funded through this lender, by volume. Each label is the loan officer's NMLS ID, so it chains straight into `GET /originators/{nmlsId}`. Loans with no identified loan officer are excluded rather than collapsed into one unnavigable bucket.","operationId":"lenderOriginators","parameters":[{"description":"Lender canonical-name ID","in":"path","name":"id","required":true,"schema":{"description":"Lender canonical-name ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of this lender's loans by originators"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Loan officers who send business to this lender","tags":["Lenders"]}},"/v1/lenders/{id}/breakdowns/states":{"post":{"description":"Ranks the states this lender's loans were secured in, by volume. Labels are two-letter state abbreviations.","operationId":"lenderStates","parameters":[{"description":"Lender canonical-name ID","in":"path","name":"id","required":true,"schema":{"description":"Lender canonical-name ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of this lender's loans by states"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"State volume breakdown across this lender's loans","tags":["Lenders"]}},"/v1/loans":{"post":{"description":"Search and list individual public-record mortgage and deed loan records — one row per loan (purchase, refinance, origination). Filter by geography (state, county, city, zip), lender, originator, loan amount, interest rate, loan type/purpose, and recording date, with sorting and cursor pagination. This is the discrete per-loan record search: use it to find specific loans or build a filtered loan list. Each row carries the property address, loan terms, the originating loan officer, and `borrowerStatus` — so this is also how you pull a loan officer's own funded production (\"my closed loans\", \"my past clients\", \"my book of business\"): filter by `originator` (their NMLS id), and add `borrowerStatus` for borrowers still in the home — that is the five current-owner codes (`Current`, `R_CWCLO`, `R_CWNLO`, `E_CWCLO`, `E_CWNLO`), NOT `\"Current\"` alone, which omits everyone who has since refinanced. That is market data, not CRM data — it does not require the loan officer to have added anything to a CRM workspace. (For aggregate market rates and volumes use the market search; for one loan by its ID use the loan detail endpoint.) If you only need how many loans match and not the records themselves, send the same request body to `countLoans`.","operationId":"listLoans","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanListResponse"}}},"description":"Paginated list of loans"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error. Includes unresolvable location filters: a `city`/`county`/`state`/`zip` value that does not match a recognized location returns 400 rather than an empty result set. Resolve the name with `instantSearch` (use an id from its `results.locations[]`) or `suggestLocations` (use the `id` of a `source: \"dictionary\"` result), then pass that id back as the filter value."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Search individual loan records with filters","tags":["Loans"]}},"/v1/loans/analytics/chart":{"post":{"operationId":"loansAnalyticsChart","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanChartRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChartResponse"}}},"description":"Chart data. Money measures (`volume`, `avgSalePrice`, `avgListPrice`) are sentinel-guarded. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Configurable chart data (measure × slice)","tags":["Loans"]}},"/v1/loans/analytics/summary":{"post":{"operationId":"loansAnalyticsSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanSummaryRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleSummaryResponse"}}},"description":"Current + previous-period summary"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Market summary with previous-period comparison","tags":["Loans"]}},"/v1/loans/analytics/time-series":{"post":{"operationId":"loansAnalyticsTimeSeries","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanTimeSeriesRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleTimeSeriesResponse"}}},"description":"Time-series with previous-period comparison"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Volume / units over time","tags":["Loans"]}},"/v1/loans/bulk-delivery":{"post":{"description":"Queues an ECS task that dumps every matching loans document to S3 in the requested format. Returns 202 with a jobId; poll `GET /v1/loans/bulk-delivery/{jobId}` for status + the signed download URL.\n\n**Row limit.** Deliveries of up to 1,000 rows need no entitlement. Above that, the org's `bulk-delivery.loans` entitlement is required and its scope (row ceiling, row filters, allowed fields) governs the delivery; without it the request is rejected with 403 `entitlement_missing`. Pass `limit` at or below the ceiling to deliver a capped subset of a broader query. Email support@modelmatch.com to request a limit increase.\n\nDelivery is billed at 1 credit per 100 rows regardless of entitlement.","operationId":"submitLoansBulkDelivery","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/LoanListRequest"},{"additionalProperties":false,"properties":{"fields":{"description":"Optional output column projection, named by the response DTO fields (the same camelCase fields the list endpoint returns, e.g. `city`, `interestRate`). Intersected with the entitlement scope's allowedFields and the entity's full column set. If empty after intersection, falls back to all columns. It also SELECTS the opt-in columns, which are not part of the list DTO and are never delivered unless named here: `communityLending` (properties, originators, companies, branches) — the Community Lending neighborhood profile, identical to the block on the entity's detail endpoint; `parties` (properties) — the mortgage parties attributed to the parcel, by attribution scope; and `marketCount` / `countyCount` / `stateCount` / `zipCount` / `lenderCount` (originators) — the market-breadth rollups you can already filter on. In `csv` and `parquet` the two block columns are JSON-encoded cells; in `json` and `ndjson` they are nested objects.","items":{"minLength":1,"type":"string"},"type":"array"},"format":{"$ref":"#/components/schemas/BulkDeliveryFormat"},"limit":{"description":"Optional hard cap on the number of rows delivered — and therefore billed (1 credit / 100 rows). The job delivers the first `limit` rows in sort order (default newest-first) and bills only for those. If the query matches fewer than `limit`, all matches are delivered. Distinct from the page-size `size` field, which is ignored on this endpoint. The row ceiling still applies — 1,000 without the entity's bulk-delivery entitlement, or the entitlement's `maxRows` with it. A `limit` above the ceiling is rejected, but a `limit` at or below it lets you export a capped top-N even when the full match exceeds the ceiling — which is the intended way to run a broad query under the 1,000-row allowance.","example":1000,"exclusiveMinimum":true,"minimum":0,"type":"integer"}},"required":["format"],"type":"object"}]}}}},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliverySubmitResponse"}}},"description":"Job queued; ECS task launched"},"400":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/BulkDeliveryPreflightExceeded"}]}}},"description":"Validation failure OR delivery would exceed the entitlement's maxRows"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryInsufficientCredits"}}},"description":"Insufficient credits (balance < estimatedTotal / 100)"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryForbidden"}}},"description":"Delivery exceeds the 1,000-row limit available without the `bulk-delivery.loans` entitlement. Lower `limit`, narrow the filters, or contact support for a limit increase."},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Preflight / S3 / DDB / ECS launch failure"}},"summary":"Submit a bulk-delivery job for loans","tags":["Loans"]}},"/v1/loans/bulk-delivery/{jobId}":{"get":{"operationId":"getLoansBulkDeliveryJob","parameters":[{"description":"Job ID returned by `POST /v1/loans/bulk-delivery`","in":"path","name":"jobId","required":true,"schema":{"description":"Job ID returned by `POST /v1/loans/bulk-delivery`","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryStatusResponse"}}},"description":"Job status (resultsUrl re-signed if completed)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Caller does not own this job"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Job not found (or expired past 30d TTL)"}},"summary":"Get bulk-delivery job status for loans","tags":["Loans"]}},"/v1/loans/count":{"post":{"description":"Return the exact number of loans matching the given filters. Accepts the same request body as `listLoans` (pagination and sort are ignored). Use this when you only need a total; to get the matching loans themselves, send the same request body to `listLoans`.","operationId":"countLoans","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountResponse"}}},"description":"Exact count of matching loans"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Count loans matching filters","tags":["Loans"],"x-mm-records-via":"listLoans"}},"/v1/loans/{id}":{"get":{"operationId":"getLoan","parameters":[{"description":"Loan ID","in":"path","name":"id","required":true,"schema":{"description":"Loan ID","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanDetailResponse"}}},"description":"Loan detail"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Loan not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large"}},"summary":"Get loan by ID","tags":["Loans"]}},"/v1/loans/{id}/related":{"get":{"description":"Return the ids of records of another type that are linked to this record. Links resolve by identifier, strongest identifier first, and equally-trusted identifiers are combined — a company's linked loans cover every role it holds on a loan, not just the first one found. The response reports which strength was used: `primary` is the canonical identifier for that pair, `secondary` is a real but weaker alternate used only when the record carries nothing better. This is a lightweight index: it returns ids and a count, not full records. For filtering, sorting, pagination and full detail, use the named endpoint for the pair (for example the originator loans endpoint) and fetch records by id.","operationId":"loanRelated","parameters":[{"description":"Loan id","in":"path","name":"id","required":true,"schema":{"description":"Loan id","type":"string"}},{"description":"Type of record to link to","in":"query","name":"to","required":true,"schema":{"description":"Type of record to link to","enum":["agents","companies","originators","properties","sales"],"type":"string"}},{"description":"Maximum ids to return (default 25, max 200)","in":"query","name":"limit","required":false,"schema":{"description":"Maximum ids to return (default 25, max 200)","maximum":200,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelatedResponse"}}},"description":"Linked record ids"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Record not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Records linked to this one","tags":["Related"]}},"/v1/locations/retrieve/{mapboxId}":{"get":{"description":"Retrieve normalized location details (city, state, county, zip, coordinates) for a suggestion ID from `suggestLocations`. A location dictionary id resolves from Model Match's own data and echoes back its `id`; any other id resolves through Mapbox.","operationId":"retrieveLocation","parameters":[{"description":"Mapbox suggestion ID","in":"path","name":"mapboxId","required":true,"schema":{"description":"Mapbox suggestion ID","minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationRetrieveResponse"}}},"description":"Normalized location details"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Retrieve normalized location details","tags":["Locations"]}},"/v1/locations/suggest":{"get":{"description":"Autocomplete location search. Cities and counties come from Model Match's own location dictionary and carry an `id` (e.g. `city_mo_saint-louis`) that city / county filters accept — including for places our data spells differently than a mapping provider does. Street addresses come from Mapbox. Use the `mapbox_id` from any suggestion with `retrieveLocation` to get normalized geographic details and coordinates.","operationId":"suggestLocations","parameters":[{"description":"Search text","in":"query","name":"q","required":true,"schema":{"description":"Search text","minLength":1,"type":"string"}},{"description":"Max results (1-10, default 5)","in":"query","name":"limit","required":false,"schema":{"default":5,"description":"Max results (1-10, default 5)","maximum":10,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationSuggestResponse"}}},"description":"Location suggestions"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Autocomplete location search","tags":["Locations"]}},"/v1/market":{"post":{"description":"Search aggregated loan origination market data. Filterable dimensions cover geography (state, county, zip), product (loan purpose / type / amortization), borrower demographics, and loan numerics.","operationId":"listMarket","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketListResponse"}}},"description":"Paginated list of market records"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error. Includes unresolvable location filters: a `city`/`county`/`state`/`zip` value that does not match a recognized location returns 400 rather than an empty result set. Resolve the name with `instantSearch` (use an id from its `results.locations[]`) or `suggestLocations` (use the `id` of a `source: \"dictionary\"` result), then pass that id back as the filter value."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Search aggregated market data with filters","tags":["Market"]}},"/v1/market/analytics/chart":{"post":{"operationId":"marketAnalyticsChart","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketChartRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChartResponse"}}},"description":"Chart data with measure/slice breakdown"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Market measure by dimension breakdown","tags":["Market"]}},"/v1/market/analytics/summary":{"post":{"operationId":"marketAnalyticsSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketSummaryRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketSummaryResponse"}}},"description":"13 market metrics + previous-period comparison"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Market summary (volume, units, rate, loan amount, credit score, LTV, DTI, income, etc.) with previous-period comparison","tags":["Market"]}},"/v1/market/analytics/time-series":{"post":{"operationId":"marketAnalyticsTimeSeries","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketTimeSeriesRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketTimeSeriesResponse"}}},"description":"Time series with previous-period comparison. Each bucket carries `volume`, `units`, and `measureValue` for the requested `measure`."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Market metrics over time","tags":["Market"]}},"/v1/market/community-lending":{"post":{"description":"The aggregate Community Lending profile of the originations matching your filters: the share that landed in low- or moderate-income neighborhoods, the CRA-eligible share, the distribution across the four neighborhood income bands, and the majority-minority neighborhood share. Values describe the U.S. Census tract (neighborhood) as a whole — tract-level aggregate statistics, never an individual, household or applicant attribute. Percentages are 0-100. This is a MARKET-LEVEL view only — the underlying origination data carries no lender, loan officer or borrower identity, and no figure here is attributable to one. Every share is reported next to the count it is a share of, because the three designations have three different coverage levels; read the denominator before comparing markets.","operationId":"marketCommunityLending","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketCommunityLendingRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketCommunityLendingResponse"}}},"description":"Community Lending mix, optionally sliced by dimension"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Community Lending mix of a market's originations","tags":["Market"]}},"/v1/me":{"get":{"description":"Identity, active organization + membership role, and how the caller authenticated.\n\nExtended profile fields (`nmlsId`, `jobRole`, the contact-card block) are resolved for every caller type — session-cookie, API-key, and OAuth-bearer alike. `auth.profileResolved` is `true` on any successful read; it is retained for compatibility and no longer varies by the credential the caller presented.","operationId":"getMe","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeResponse"}}},"description":"The caller's account"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountServiceUnavailable"}}},"description":"Account service unavailable"}},"summary":"Get the current caller's account","tags":["Me"]},"patch":{"description":"Partial update — send only the fields that change; `null` clears one. Returns the account in the same shape as `GET /v1/me`.\n\n`email` is NOT updatable here: changing it runs a verification flow. Sending it is a 400, not a silent no-op.","operationId":"updateMe","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeUpdateRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeResponse"}}},"description":"The updated account"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountServiceUnavailable"}}},"description":"Account service unavailable"}},"summary":"Update the current caller's profile","tags":["Me"]}},"/v1/me/credits":{"get":{"description":"Balance split by bucket (cycle allowance, purchased on-demand, personal), the per-cycle allowance and on-demand unit price, and ledger totals over a window.\n\nThe window defaults to the current calendar month to date (UTC). Figures are for the caller's own membership in their active organization — the same organization the API meters requests against.","operationId":"getMeCredits","parameters":[{"description":"Usage window start (YYYY-MM-DD, inclusive)","in":"query","name":"startDate","required":false,"schema":{"description":"Usage window start (YYYY-MM-DD, inclusive)","pattern":"^\\d{4}-\\d{2}-\\d{2}$/u","type":"string"}},{"description":"Usage window end (YYYY-MM-DD, inclusive)","in":"query","name":"endDate","required":false,"schema":{"description":"Usage window end (YYYY-MM-DD, inclusive)","pattern":"^\\d{4}-\\d{2}-\\d{2}$/u","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeCreditsResponse"}}},"description":"Credit balance and usage"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountServiceUnavailable"}}},"description":"Account service unavailable"}},"summary":"Get the caller's credit balance and usage","tags":["Me"]}},"/v1/me/plan":{"get":{"description":"The active organization's resolved plan (with its limit map), the subscription status backing it, and the plan grants attached to the organization and to the user.\n\n`plan` is null when the workspace has no active, trialing, or past-due subscription. No billing details (invoices, payment methods) are exposed.","operationId":"getMePlan","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MePlanResponse"}}},"description":"The caller's plan"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountServiceUnavailable"}}},"description":"Account service unavailable"}},"summary":"Get the caller's current plan","tags":["Me"]}},"/v1/offices":{"post":{"description":"NOT NMLS mortgage branches — use `/branches` for those. Returns office name, address, agent count, coordinates, and office-level production for the selected period. Default sort is by agent count descending. If you only need how many offices match and not the records themselves, send the same request body to `countOffices`.","operationId":"listOffices","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfficeListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfficeListResponse"}}},"description":"Paginated list of offices"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Search real-estate offices with filters","tags":["Offices"]}},"/v1/offices/agents":{"post":{"operationId":"officeAgents","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfficeAgentsRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentListResponse"}}},"description":"Paginated list of agents at the office"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Agents at an office","tags":["Offices"]}},"/v1/offices/count":{"post":{"description":"Return the exact number of offices matching the given filters. Accepts the same request body as `listOffices` (pagination and sort are ignored). Use this when you only need a total; to get the matching offices themselves, send the same request body to `listOffices`.","operationId":"countOffices","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfficeListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountResponse"}}},"description":"Exact count of matching offices"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Count offices matching filters","tags":["Offices"],"x-mm-records-via":"listOffices"}},"/v1/offices/{id}":{"get":{"operationId":"getOffice","parameters":[{"description":"Office key (mm_office_key)","in":"path","name":"id","required":true,"schema":{"description":"Office key (mm_office_key)","type":"string"}},{"description":"Period for production metrics (default: last12Months)","in":"query","name":"period","required":false,"schema":{"allOf":[{"$ref":"#/components/schemas/Period"},{"description":"Period for production metrics (default: last12Months)"}]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfficeDetailResponse"}}},"description":"Office detail"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Office not found"}},"summary":"Get office by key with office-level production","tags":["Offices"]}},"/v1/originators":{"post":{"description":"Search and list individual loan originators (LOs — NMLS-registered mortgage loan officers) with filters — one row per originator. Filter by name, NMLS ID, location (state, city), employer/company, and production metrics (loan volume, units, product mix), with sorting and cursor pagination. LOCATION SEMANTICS: the state/city filters match an originator's PRODUCTION GEOGRAPHY — the markets where they actually originated loans in the selected period — not where their office or employer sits. An LO who lends across several markets matches a filter for ANY of those markets, while the `state`/`city` returned on each row reflect only their PRIMARY (highest-volume) market. So a search for city \"Long Beach\" can return an LO whose displayed location is a different city/state (e.g. their top market is in Arizona) — they still originated loans in Long Beach, it just isn't their #1 market. To rank originators by their volume within a specific market, sort by volume after filtering, or use the per-originator city/county/state breakdown endpoints. This is the per-originator record search: use it to find specific loan officers or build a filtered LO list. (For a single originator by NMLS ID use the originator detail endpoint.) If you only need how many originators match and not the records themselves, send the same request body to `countOriginators`.","operationId":"listOriginators","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorListResponse"}}},"description":"Paginated list of originators"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error. Includes unresolvable location filters: a `city`/`county`/`state`/`zip` value that does not match a recognized location returns 400 rather than an empty result set. Resolve the name with `instantSearch` (use an id from its `results.locations[]`) or `suggestLocations` (use the `id` of a `source: \"dictionary\"` result), then pass that id back as the filter value."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Search originators with filters","tags":["Originators"]}},"/v1/originators/analytics/chart":{"post":{"operationId":"originatorAnalyticsChart","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorChartRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChartResponse"}}},"description":"Chart data. Money measures (`volume`, `avgSalePrice`, `avgListPrice`) are sentinel-guarded. Excludes values outside 0–100,000,000 — the source encodes unknown values as an out-of-range fill, and averaging them raw is wrong by orders of magnitude. The bound is applied before the metric and is not part of the public filter surface, so an equivalent range filter will not reproduce this figure exactly."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Configurable chart (measure × slice) over one LO's loans","tags":["Originators"]}},"/v1/originators/analytics/summary":{"post":{"operationId":"originatorAnalyticsSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorSummaryRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleSummaryResponse"}}},"description":"Current + previous-period summary"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Production summary with previous-period comparison","tags":["Originators"]}},"/v1/originators/analytics/time-series":{"post":{"operationId":"originatorAnalyticsTimeSeries","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorTimeSeriesRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleTimeSeriesResponse"}}},"description":"Time-series with previous-period comparison"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Originator volume / units over time","tags":["Originators"]}},"/v1/originators/bulk-delivery":{"post":{"description":"Queues an ECS task that dumps every matching originators document to S3 in the requested format. Returns 202 with a jobId; poll `GET /v1/originators/bulk-delivery/{jobId}` for status + the signed download URL.\n\n**Row limit.** Deliveries of up to 1,000 rows need no entitlement. Above that, the org's `bulk-delivery.originators` entitlement is required and its scope (row ceiling, row filters, allowed fields) governs the delivery; without it the request is rejected with 403 `entitlement_missing`. Pass `limit` at or below the ceiling to deliver a capped subset of a broader query. Email support@modelmatch.com to request a limit increase.\n\nDelivery is billed at 1 credit per 100 rows regardless of entitlement.","operationId":"submitOriginatorsBulkDelivery","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/OriginatorListRequest"},{"additionalProperties":false,"properties":{"fields":{"description":"Optional output column projection, named by the response DTO fields (the same camelCase fields the list endpoint returns, e.g. `city`, `interestRate`). Intersected with the entitlement scope's allowedFields and the entity's full column set. If empty after intersection, falls back to all columns. It also SELECTS the opt-in columns, which are not part of the list DTO and are never delivered unless named here: `communityLending` (properties, originators, companies, branches) — the Community Lending neighborhood profile, identical to the block on the entity's detail endpoint; `parties` (properties) — the mortgage parties attributed to the parcel, by attribution scope; and `marketCount` / `countyCount` / `stateCount` / `zipCount` / `lenderCount` (originators) — the market-breadth rollups you can already filter on. In `csv` and `parquet` the two block columns are JSON-encoded cells; in `json` and `ndjson` they are nested objects.","items":{"minLength":1,"type":"string"},"type":"array"},"format":{"$ref":"#/components/schemas/BulkDeliveryFormat"},"limit":{"description":"Optional hard cap on the number of rows delivered — and therefore billed (1 credit / 100 rows). The job delivers the first `limit` rows in sort order (default newest-first) and bills only for those. If the query matches fewer than `limit`, all matches are delivered. Distinct from the page-size `size` field, which is ignored on this endpoint. The row ceiling still applies — 1,000 without the entity's bulk-delivery entitlement, or the entitlement's `maxRows` with it. A `limit` above the ceiling is rejected, but a `limit` at or below it lets you export a capped top-N even when the full match exceeds the ceiling — which is the intended way to run a broad query under the 1,000-row allowance.","example":1000,"exclusiveMinimum":true,"minimum":0,"type":"integer"}},"required":["format"],"type":"object"}]}}}},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliverySubmitResponse"}}},"description":"Job queued; ECS task launched"},"400":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/BulkDeliveryPreflightExceeded"}]}}},"description":"Validation failure OR delivery would exceed the entitlement's maxRows"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryInsufficientCredits"}}},"description":"Insufficient credits (balance < estimatedTotal / 100)"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryForbidden"}}},"description":"Delivery exceeds the 1,000-row limit available without the `bulk-delivery.originators` entitlement. Lower `limit`, narrow the filters, or contact support for a limit increase."},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Preflight / S3 / DDB / ECS launch failure"}},"summary":"Submit a bulk-delivery job for originators","tags":["Originators"]}},"/v1/originators/bulk-delivery/{jobId}":{"get":{"operationId":"getOriginatorsBulkDeliveryJob","parameters":[{"description":"Job ID returned by `POST /v1/originators/bulk-delivery`","in":"path","name":"jobId","required":true,"schema":{"description":"Job ID returned by `POST /v1/originators/bulk-delivery`","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryStatusResponse"}}},"description":"Job status (resultsUrl re-signed if completed)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Caller does not own this job"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Job not found (or expired past 30d TTL)"}},"summary":"Get bulk-delivery job status for originators","tags":["Originators"]}},"/v1/originators/count":{"post":{"description":"Return the exact number of originators matching the given filters. Accepts the same request body as `listOriginators` (pagination and sort are ignored). Use this when you only need a total; to get the matching originators themselves, send the same request body to `listOriginators`.","operationId":"countOriginators","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountResponse"}}},"description":"Exact count of matching originators"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Count originators matching filters","tags":["Originators"],"x-mm-records-via":"listOriginators"}},"/v1/originators/{id}/related":{"get":{"description":"Return the ids of records of another type that are linked to this record. Links resolve by identifier, strongest identifier first, and equally-trusted identifiers are combined — a company's linked loans cover every role it holds on a loan, not just the first one found. The response reports which strength was used: `primary` is the canonical identifier for that pair, `secondary` is a real but weaker alternate used only when the record carries nothing better. This is a lightweight index: it returns ids and a count, not full records. For filtering, sorting, pagination and full detail, use the named endpoint for the pair (for example the originator loans endpoint) and fetch records by id.","operationId":"originatorRelated","parameters":[{"description":"Originator NMLS ID","in":"path","name":"id","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}},{"description":"Type of record to link to","in":"query","name":"to","required":true,"schema":{"description":"Type of record to link to","enum":["companies","loans","properties"],"type":"string"}},{"description":"Maximum ids to return (default 25, max 200)","in":"query","name":"limit","required":false,"schema":{"description":"Maximum ids to return (default 25, max 200)","maximum":200,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelatedResponse"}}},"description":"Linked record ids"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Record not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Records linked to this one","tags":["Related"]}},"/v1/originators/{nmlsId}":{"get":{"operationId":"getOriginator","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}},{"description":"Period for volume/units (default: last12Months)","in":"query","name":"period","required":false,"schema":{"allOf":[{"$ref":"#/components/schemas/Period"},{"description":"Period for volume/units (default: last12Months)"}]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorDetailResponse"}}},"description":"Originator detail"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Originator not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large"}},"summary":"Get originator by NMLS ID","tags":["Originators"]}},"/v1/originators/{nmlsId}/breakdowns/agents":{"post":{"description":"Ranks the real-estate agents on the selling side of this LO's loans, by volume. Buckets whose name is an MLS placeholder for \"no selling agent recorded\" (`non member`, `non listed agent`, and ~140 board-specific spellings) are excluded rather than ranked as agents — they are not people and cannot be resolved with `GET /v1/agents/{id}`. Percentages are shares of the LO's whole loan population, so they do not sum to 100 across the page.","operationId":"originatorAgents","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by agents"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Real-estate agents this LO co-closed with","tags":["Originators"]}},"/v1/originators/{nmlsId}/breakdowns/branches":{"post":{"operationId":"originatorBranches","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by branches"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Branch (broker) history for this LO","tags":["Originators"]}},"/v1/originators/{nmlsId}/breakdowns/brokers":{"post":{"operationId":"originatorBrokers","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by brokers"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Broker shops this LO originated loans through (name-resolved)","tags":["Originators"]}},"/v1/originators/{nmlsId}/breakdowns/cities":{"post":{"operationId":"originatorCitiesBreakdown","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by cities"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"City volume breakdown across this LO's loans","tags":["Originators"]}},"/v1/originators/{nmlsId}/breakdowns/companies":{"post":{"operationId":"originatorCompanies","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by companies"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Funding companies (employer history) for this LO","tags":["Originators"]}},"/v1/originators/{nmlsId}/breakdowns/counties":{"post":{"operationId":"originatorCountiesBreakdown","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by counties"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"County (FIPS) volume breakdown across this LO's loans","tags":["Originators"]}},"/v1/originators/{nmlsId}/breakdowns/lenders":{"post":{"operationId":"originatorLenders","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by lenders"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Lenders this LO has originated through","tags":["Originators"]}},"/v1/originators/{nmlsId}/breakdowns/offices":{"post":{"operationId":"originatorOffices","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by broker (office)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Real-estate offices this LO closed through (with sponsoring company)","tags":["Originators"]}},"/v1/originators/{nmlsId}/breakdowns/states":{"post":{"operationId":"originatorStatesBreakdown","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by states"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"State volume breakdown across this LO's loans","tags":["Originators"]}},"/v1/originators/{nmlsId}/breakdowns/zip-codes":{"post":{"operationId":"originatorZipCodes","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"}}},"description":"Breakdown of the LO's loans by zip-codes"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Zip-code volume breakdown","tags":["Originators"]}},"/v1/originators/{nmlsId}/loans":{"post":{"operationId":"originatorLoans","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoanListResponse"}}},"description":"Paginated list of loans originated by this LO"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Loans originated by this LO","tags":["Originators"]}},"/v1/originators/{nmlsId}/markets":{"post":{"description":"One blended view of a loan officer's lending footprint: the ZIP codes they originated in, city / county / state rollups of the same scope, and the period totals those markets are a share of. AVERAGES ARE VOLUME-WEIGHTED: the summary loan size is Σ volume ÷ Σ units, not an unweighted mean of the per-market averages (on a real footprint the two differ by thousands of dollars). Sending `zipCodes` narrows every grain to those ZIPs; sending a `dateRange` re-cuts the window. Either switches the response from the LO's pre-aggregated footprint to a live aggregation of their loans — `source` and `sourceReasons` say which was used, and bucket `key` forms differ between them (use `name` for display). All shares on this response are 0–100 percentages. A summary can cover less than the whole book: production that could not be attributed to a place is held out and reported in `summary.unresolved` rather than being folded in or silently dropped. The summary also carries a Community Lending mix — what kind of neighborhood this book lands in. These are U.S. Census tract-level aggregates describing whole neighborhoods, never individual, household or applicant attributes. Unscoped it is the LO's own whole-period mix; a ZIP or date scope recomputes it over the markets in scope, and `summary.communityLending.basis` says which you got.","operationId":"originatorMarkets","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorMarketsRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginatorMarketsResponse"}}},"description":"The LO's blended market footprint"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Originator not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"The markets this LO lends in","tags":["Originators"]}},"/v1/originators/{nmlsId}/properties":{"post":{"description":"Returns the parcels this loan officer is attributed to in public record — the reverse of the `parties` block on `GET /v1/properties/{id}`. Accepts the same filters, sorts and pagination as the main property search, so a caller can ask 'this LO's parcels in Travis County built after 2015' in one request. Attribution is ALL-TIME: a parcel stays in this LO's set after the loan is paid off, because the question is career reach rather than current book. An LO with no attributed parcels returns an empty page, not a 404 — the LO may be real and simply have nothing in the public record yet.","operationId":"originatorProperties","parameters":[{"description":"Originator NMLS ID","in":"path","name":"nmlsId","required":true,"schema":{"description":"Originator NMLS ID","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyListResponse"}}},"description":"Paginated list of parcels attributed to this LO"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Properties this loan officer has touched","tags":["Originators"]}},"/v1/properties":{"post":{"description":"Search and list individual properties/parcels with filters — one row per parcel. Filter by location (state, county, city, zip, address), owner name, property characteristics (beds, baths, square footage, year built, property type), value, and ownership or transaction history, with sorting and cursor pagination. This is the discrete per-property record search: use it to find specific properties or build a filtered property list. (For a single property by its ID use the property detail endpoint.) If you only need how many properties match and not the records themselves, send the same request body to `countProperties`.","operationId":"listProperties","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyListResponse"}}},"description":"Paginated list of properties"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Search properties with filters","tags":["Properties"]}},"/v1/properties/analytics/chart":{"post":{"operationId":"propertiesAnalyticsChart","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyChartRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChartResponse"}}},"description":"Chart data with measure/slice breakdown"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Configurable chart data (measure × slice)","tags":["Properties"]}},"/v1/properties/analytics/summary":{"post":{"operationId":"propertiesAnalyticsSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertySummaryRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyAnalyticsResponse"}}},"description":"Property count and average AVM value"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Property count and average AVM","tags":["Properties"]}},"/v1/properties/bulk-delivery":{"post":{"description":"Queues an ECS task that dumps every matching properties document to S3 in the requested format. Returns 202 with a jobId; poll `GET /v1/properties/bulk-delivery/{jobId}` for status + the signed download URL.\n\n**Row limit.** Deliveries of up to 1,000 rows need no entitlement. Above that, the org's `bulk-delivery.properties` entitlement is required and its scope (row ceiling, row filters, allowed fields) governs the delivery; without it the request is rejected with 403 `entitlement_missing`. Pass `limit` at or below the ceiling to deliver a capped subset of a broader query. Email support@modelmatch.com to request a limit increase.\n\nDelivery is billed at 1 credit per 100 rows regardless of entitlement.","operationId":"submitPropertiesBulkDelivery","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/PropertyListRequest"},{"additionalProperties":false,"properties":{"fields":{"description":"Optional output column projection, named by the response DTO fields (the same camelCase fields the list endpoint returns, e.g. `city`, `interestRate`). Intersected with the entitlement scope's allowedFields and the entity's full column set. If empty after intersection, falls back to all columns. It also SELECTS the opt-in columns, which are not part of the list DTO and are never delivered unless named here: `communityLending` (properties, originators, companies, branches) — the Community Lending neighborhood profile, identical to the block on the entity's detail endpoint; `parties` (properties) — the mortgage parties attributed to the parcel, by attribution scope; and `marketCount` / `countyCount` / `stateCount` / `zipCount` / `lenderCount` (originators) — the market-breadth rollups you can already filter on. In `csv` and `parquet` the two block columns are JSON-encoded cells; in `json` and `ndjson` they are nested objects.","items":{"minLength":1,"type":"string"},"type":"array"},"format":{"$ref":"#/components/schemas/BulkDeliveryFormat"},"limit":{"description":"Optional hard cap on the number of rows delivered — and therefore billed (1 credit / 100 rows). The job delivers the first `limit` rows in sort order (default newest-first) and bills only for those. If the query matches fewer than `limit`, all matches are delivered. Distinct from the page-size `size` field, which is ignored on this endpoint. The row ceiling still applies — 1,000 without the entity's bulk-delivery entitlement, or the entitlement's `maxRows` with it. A `limit` above the ceiling is rejected, but a `limit` at or below it lets you export a capped top-N even when the full match exceeds the ceiling — which is the intended way to run a broad query under the 1,000-row allowance.","example":1000,"exclusiveMinimum":true,"minimum":0,"type":"integer"}},"required":["format"],"type":"object"}]}}}},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliverySubmitResponse"}}},"description":"Job queued; ECS task launched"},"400":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/BulkDeliveryPreflightExceeded"}]}}},"description":"Validation failure OR delivery would exceed the entitlement's maxRows"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryInsufficientCredits"}}},"description":"Insufficient credits (balance < estimatedTotal / 100)"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryForbidden"}}},"description":"Delivery exceeds the 1,000-row limit available without the `bulk-delivery.properties` entitlement. Lower `limit`, narrow the filters, or contact support for a limit increase."},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Preflight / S3 / DDB / ECS launch failure"}},"summary":"Submit a bulk-delivery job for properties","tags":["Properties"]}},"/v1/properties/bulk-delivery/{jobId}":{"get":{"operationId":"getPropertiesBulkDeliveryJob","parameters":[{"description":"Job ID returned by `POST /v1/properties/bulk-delivery`","in":"path","name":"jobId","required":true,"schema":{"description":"Job ID returned by `POST /v1/properties/bulk-delivery`","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeliveryStatusResponse"}}},"description":"Job status (resultsUrl re-signed if completed)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Caller does not own this job"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Job not found (or expired past 30d TTL)"}},"summary":"Get bulk-delivery job status for properties","tags":["Properties"]}},"/v1/properties/count":{"post":{"description":"Return the exact number of properties matching the given filters. Accepts the same request body as `listProperties` (pagination and sort are ignored). Use this when you only need a total; to get the matching properties themselves, send the same request body to `listProperties`.","operationId":"countProperties","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountResponse"}}},"description":"Exact count of matching properties"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Count properties matching filters","tags":["Properties"],"x-mm-records-via":"listProperties"}},"/v1/properties/enrich":{"post":{"description":"Looks up owner contact information for up to 50 properties in a single synchronous request. Each id is resolved independently and returned in the `results` array with its own status — a bad id never fails the batch. Each match debits one credit; cache hits and no-matches are free. Every ok item also carries `property` — the parcel's Community Lending neighborhood profile and mortgage party rosters. For larger sets use the asynchronous bulk job.","operationId":"enrichPropertiesBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichBatchRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichBatchResponse"}}},"description":"Per-item results (each cached, fresh, or errored)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Invalid request (Zod validation failure)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"}},"summary":"Enrich several properties with owner contact info in one request","tags":["Properties"]}},"/v1/properties/enrich-bulk":{"post":{"description":"Queues an ECS task that enriches up to 50000 properties. Returns 202 with a jobId; poll `GET /v1/properties/enrich-bulk/{jobId}` or subscribe to the `enrichment.bulk.*` EventBridge / webhook events for completion.","operationId":"enrichPropertiesBulk","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichBulkRequest"}}}},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichBulkResponse"}}},"description":"Job queued; ECS task launched"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Invalid request (Zod validation failure)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"402":{"content":{"application/json":{"schema":{"properties":{"balance":{"description":"Remaining credit balance the charge saw.","type":"number"},"cost":{"description":"Credits the request asked for.","type":"number"},"error":{"enum":["payment_required"],"type":"string"},"message":{"description":"Human-readable explanation of the decline.","type":"string"},"reason":{"description":"Why the charge was declined, when known: `out_of_credits` (balance empty) vs. `limit_reached` (a spend cap was hit).","enum":["out_of_credits","limit_reached"],"type":"string"}},"required":["error","balance","cost"],"type":"object"}}},"description":"Insufficient credits (balance < the job's targeted property count)"},"429":{"content":{"application/json":{"schema":{"properties":{"category":{"enum":["enrichment"],"type":"string"},"error":{"enum":["daily_limit_exceeded"],"type":"string"},"limit":{"description":"The daily cap.","type":"number"},"message":{"type":"string"},"requested":{"description":"Upper bound of this job's charge (one credit per id).","type":"number"},"used":{"description":"Credits already used against today's cap.","type":"number"}},"required":["error","category","used","limit","requested","message"],"type":"object"}}},"description":"Job's max charge (one per targeted property) would exceed the member's daily enrichment cap (`daily_limit_exceeded`)"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Failed to launch task or stage inputs"}},"summary":"Submit a bulk skip-trace job","tags":["Properties"]}},"/v1/properties/enrich-bulk/{jobId}":{"get":{"operationId":"getEnrichBulkJob","parameters":[{"description":"Job ID from `POST /v1/properties/enrich-bulk`","in":"path","name":"jobId","required":true,"schema":{"description":"Job ID from `POST /v1/properties/enrich-bulk`","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichBulkJobResponse"}}},"description":"Job status (resultsUrl re-signed if completed)"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Caller does not own this job"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Job not found (or expired past 30d TTL)"}},"summary":"Get bulk enrichment job status","tags":["Properties"]}},"/v1/properties/enrichments":{"get":{"operationId":"listEnrichments","parameters":[{"description":"Maximum number of items to return (default 25)","in":"query","name":"limit","required":false,"schema":{"description":"Maximum number of items to return (default 25)","maximum":100,"minimum":1,"type":"integer"}},{"description":"Pagination cursor from a previous response","in":"query","name":"cursor","required":false,"schema":{"description":"Pagination cursor from a previous response","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichmentListResponse"}}},"description":"Paginated list of enriched properties"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"}},"summary":"List enriched properties for the current user","tags":["Properties"]}},"/v1/properties/search":{"post":{"description":"Find properties by a single free-text query — a full or partial address, an owner name, or a place. Results are ranked by relevance and tolerate typos, missing components, and reordered street directionals (e.g. \"112 5th ave nw\" and \"112 nw 5th ave\" both match). Returns the same property summary rows as the list endpoint. Use this for a search box; use the list endpoint for structured filtering.","operationId":"searchProperties","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertySearchRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyListResponse"}}},"description":"Relevance-ranked property matches"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Free-text property search","tags":["Properties"]}},"/v1/properties/{id}":{"get":{"operationId":"getProperty","parameters":[{"description":"Property document ID","in":"path","name":"id","required":true,"schema":{"description":"Property document ID","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyDetailResponse"}}},"description":"Property detail"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Property not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large"}},"summary":"Get property by ID (with mm_property_id fallback)","tags":["Properties"]}},"/v1/properties/{id}/enrich":{"post":{"description":"Looks up owner contact information via skip-trace. Uses the canonical address first; falls back to an associated loan or sale record address if the canonical is missing. The response also carries `property` — the parcel's Community Lending neighborhood profile and its mortgage party rosters, the same blocks `GET /v1/properties/{id}` returns — so the two questions that follow a skip-trace do not need a second call. `property` is `null` when the id resolves to more than one parcel and the request was served from cache (a fresh lookup 409s instead, rather than bill for a guess).","operationId":"enrichProperty","parameters":[{"description":"Property document ID. Use the `id` or `mmPropertyId` returned by a property search/detail, or the `mmPropertyId` on a loan/sale record (e.g. `mm_37035375304734463`). Do NOT pass a bare APN, a fips+apn string, or a `loan_…` id — those will not resolve.","in":"path","name":"id","required":true,"schema":{"description":"Property document ID. Use the `id` or `mmPropertyId` returned by a property search/detail, or the `mmPropertyId` on a loan/sale record (e.g. `mm_37035375304734463`). Do NOT pass a bare APN, a fips+apn string, or a `loan_…` id — those will not resolve.","type":"string"}},{"description":"When 'true', bypass both the per-member entitlement and the internal property cache, force a fresh skip-trace, and re-charge the user. Default: 'false'.","in":"query","name":"refresh","required":false,"schema":{"description":"When 'true', bypass both the per-member entitlement and the internal property cache, force a fresh skip-trace, and re-charge the user. Default: 'false'.","enum":["true","false"],"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichPropertyResponse"}}},"description":"Enrichment data (cached or fresh)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Property has no usable address on the parcel or any associated record"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Authentication required"},"402":{"content":{"application/json":{"schema":{"properties":{"balance":{"description":"Remaining credit balance the charge saw.","type":"number"},"cost":{"description":"Credits the request asked for.","type":"number"},"error":{"enum":["payment_required"],"type":"string"},"message":{"description":"Human-readable explanation of the decline.","type":"string"},"reason":{"description":"Why the charge was declined, when known: `out_of_credits` (balance empty) vs. `limit_reached` (a spend cap was hit).","enum":["out_of_credits","limit_reached"],"type":"string"}},"required":["error","balance","cost"],"type":"object"}}},"description":"Insufficient credits"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Caller lacks permission to charge credits (`permission_denied`)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Property not found, or the caller is not a member of the org (`member_not_found`)"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichAmbiguousRef"}}},"description":"The id resolved to more than one parcel (a non-unique `mm_property_id` colliding across units). Pass one of `alternates` (an exact `id`) to enrich a specific unit. NOT charged."},"429":{"content":{"application/json":{"schema":{"properties":{"category":{"description":"Usage category that was capped, when reported.","type":"string"},"error":{"enum":["rate_limited","daily_limit_exceeded"],"type":"string"},"limit":{"description":"The cap, when known.","type":"number"},"message":{"description":"Human-readable explanation of the throttle.","type":"string"},"requested":{"description":"Credits this request asked for, when known.","type":"number"},"used":{"description":"Credits already used in the window, when known.","type":"number"}},"required":["error"],"type":"object"}}},"description":"Throttled — `daily_limit_exceeded` (daily category cap) or `rate_limited` (generic limiter)"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Enrichment provider error"}},"summary":"Enrich a property with owner contact info","tags":["Properties"]}},"/v1/properties/{id}/related":{"get":{"description":"Return the ids of records of another type that are linked to this record. Links resolve by identifier, strongest identifier first, and equally-trusted identifiers are combined — a company's linked loans cover every role it holds on a loan, not just the first one found. The response reports which strength was used: `primary` is the canonical identifier for that pair, `secondary` is a real but weaker alternate used only when the record carries nothing better. This is a lightweight index: it returns ids and a count, not full records. For filtering, sorting, pagination and full detail, use the named endpoint for the pair (for example the originator loans endpoint) and fetch records by id.","operationId":"propertyRelated","parameters":[{"description":"Property id","in":"path","name":"id","required":true,"schema":{"description":"Property id","type":"string"}},{"description":"Type of record to link to","in":"query","name":"to","required":true,"schema":{"description":"Type of record to link to","enum":["companies","loans","originators","sales"],"type":"string"}},{"description":"Maximum ids to return (default 25, max 200)","in":"query","name":"limit","required":false,"schema":{"description":"Maximum ids to return (default 25, max 200)","maximum":200,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelatedResponse"}}},"description":"Linked record ids"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Record not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Records linked to this one","tags":["Related"]}},"/v1/realtime/config":{"get":{"description":"Returns the realtime/notifications connection info (endpoint, authorizer, app, stage) merged with the caller's userId, so a trusted client can connect to its per-user IoT MQTT topic.","operationId":"getRealtimeConfig","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RealtimeConfigResponse"}}},"description":"Realtime connection config"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RealtimeConfigUnavailable"}}},"description":"Realtime backend not configured"}},"summary":"Get realtime connection config","tags":["Realtime"]}},"/v1/sales":{"post":{"description":"Search and list individual real-estate sale transactions and active listings with filters — one row per sale/listing. Filter by location (state, county, city, zip), sale price, sale or listing date, property characteristics (beds, baths, square footage, property type), and listing status, with sorting and cursor pagination. This is the discrete per-transaction sales-record search: use it to find specific sales or build a filtered list of sold/active listings. If you only need how many sales match and not the records themselves, send the same request body to `countSales`.","operationId":"listSales","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaleListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaleListResponse"}}},"description":"Paginated list of sales"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error. Includes unresolvable location filters: a `city`/`county`/`state`/`zip` value that does not match a recognized location returns 400 rather than an empty result set. Resolve the name with `instantSearch` (use an id from its `results.locations[]`) or `suggestLocations` (use the `id` of a `source: \"dictionary\"` result), then pass that id back as the filter value."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Search sales with filters","tags":["Sales"]}},"/v1/sales/analytics/chart":{"post":{"operationId":"salesAnalyticsChart","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaleChartRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChartResponse"}}},"description":"Chart data"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Configurable chart (measure × slice) over the market","tags":["Sales"]}},"/v1/sales/analytics/summary":{"post":{"operationId":"salesAnalyticsSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaleSummaryRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SidedSummaryResponse"}}},"description":"Sided market summary with previous-period comparison"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Market summary with buyer/seller/dual split + previous period","tags":["Sales"]}},"/v1/sales/analytics/time-series":{"post":{"operationId":"salesAnalyticsTimeSeries","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaleTimeSeriesRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalesTimeSeriesResponse"}}},"description":"Time-series with side splits + previous period. Every side carries `volume`, `units`, and `measureValue` for the requested `measure`."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Volume/units over time with buyer/seller/dual split","tags":["Sales"]}},"/v1/sales/count":{"post":{"description":"Return the exact number of sales matching the given filters. Accepts the same request body as `listSales` (pagination and sort are ignored). Use this when you only need a total; to get the matching sales themselves, send the same request body to `listSales`.","operationId":"countSales","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaleListRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountResponse"}}},"description":"Exact count of matching sales"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Count sales matching filters","tags":["Sales"],"x-mm-records-via":"listSales"}},"/v1/sales/{id}":{"get":{"operationId":"getSale","parameters":[{"description":"Sale document ID","in":"path","name":"id","required":true,"schema":{"description":"Sale document ID","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaleDetailResponse"}}},"description":"Sale detail"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Sale not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large"}},"summary":"Get sale by ID","tags":["Sales"]}},"/v1/sales/{id}/related":{"get":{"description":"Return the ids of records of another type that are linked to this record. Links resolve by identifier, strongest identifier first, and equally-trusted identifiers are combined — a company's linked loans cover every role it holds on a loan, not just the first one found. The response reports which strength was used: `primary` is the canonical identifier for that pair, `secondary` is a real but weaker alternate used only when the record carries nothing better. This is a lightweight index: it returns ids and a count, not full records. For filtering, sorting, pagination and full detail, use the named endpoint for the pair (for example the originator loans endpoint) and fetch records by id.","operationId":"saleRelated","parameters":[{"description":"Sale id","in":"path","name":"id","required":true,"schema":{"description":"Sale id","type":"string"}},{"description":"Type of record to link to","in":"query","name":"to","required":true,"schema":{"description":"Type of record to link to","enum":["agents","loans","properties"],"type":"string"}},{"description":"Maximum ids to return (default 25, max 200)","in":"query","name":"limit","required":false,"schema":{"description":"Maximum ids to return (default 25, max 200)","maximum":200,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelatedResponse"}}},"description":"Linked record ids"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Record not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"}},"summary":"Records linked to this one","tags":["Related"]}},"/v1/search-token":{"get":{"description":"Returns a short-lived scoped search token plus the host to query, so a trusted client can search the entity indexes directly with per-query controls (e.g. attributesToSearchOn for name-only matching).","operationId":"getSearchToken","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTokenResponse"}}},"description":"Scoped search token"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Validation error"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden (authenticated, but missing required context — e.g. no active organization)"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadTooLarge"}}},"description":"Response payload too large — detail endpoint capped to fit Lambda response limits"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTokenUnavailable"}}},"description":"Search backend not configured"}},"summary":"Mint a scoped search token","tags":["Search"]}}},"security":[{"apiKeyAuth":[]},{"bearerAuth":[]}],"tags":[{"description":"Internal admin endpoints (admin role only)","name":"Admin"},{"description":"Real estate agents","name":"Agents"},{"description":"Per-user alert settings, watchlists, and feed","name":"Alerts"},{"description":"NMLS-registered company branch offices","name":"Branches"},{"description":"NMLS-registered mortgage companies","name":"Companies"},{"description":"CRM records, lists, contacts, activity, tasks, meetings, and calls","name":"CRM"},{"description":"Send Model Match records into systems you own, such as your CRM","name":"Integrations"},{"description":"Lender name normalization dictionary","name":"Lenders"},{"description":"Public-record mortgage / deed transactions","name":"Loans"},{"description":"Location autocomplete and resolution","name":"Locations"},{"description":"Aggregated mortgage origination market data (geography, product, borrower numerics)","name":"Market"},{"description":"The current caller's account — profile, credit balance, and plan","name":"Me"},{"description":"Real-estate office records","name":"Offices"},{"description":"Loan originators (NMLS LOs)","name":"Originators"},{"description":"Properties with owners and history","name":"Properties"},{"description":"Realtime/notifications connection config","name":"Realtime"},{"description":"Records linked to a given record, across entity types","name":"Related"},{"description":"Real-estate sales transactions","name":"Sales"},{"description":"Instant multi-entity search","name":"Search"}]}