Agents
Submit a bulk-delivery job for agents
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.
Row limit. Deliveries of up to 5,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.
Delivery is billed at 1 credit per row regardless of entitlement (deliveries submitted from the ModelMatch web app are not billed).
Push-target destination. Pass destination: { type: "push-target", targetId } to have the finished rows sent to a configured push target instead of downloaded. The target is checked before anything is queued; a refusal returns the push target's status and code (TARGET_NOT_FOUND 404, FORBIDDEN 403, PLAN_REQUIRED 402, TARGET_DISABLED 409, ENTITY_MISMATCH 400). Limits and billing are the same as a file delivery.
Authorization
Body application/json
advancedFiltersone ofShow child attributesHide child attributes
Option 1objectShow child attributesHide child attributes
childrenone of[]requiredArray of filter expressions (AND)
Same shape as its parent.
typeenumrequiredandOption 2objectShow child attributesHide child attributes
childrenone of[]requiredArray of filter expressions (OR)
Same shape as its parent.
typeenumrequiredorOption 3objectShow child attributesHide child attributes
childone ofrequiredSame shape as its parent.
typeenumrequirednotOption 4objectShow child attributesHide child attributes
fieldstringrequiredopenumrequiredComparison 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.
eqneqgtgteltltebetweeninmatchgeoDistanceexiststypeenumrequiredfiltervaluenullComparison value
crmListobjectScope the result to the caller's CRM. Resolved against the caller's ACTIVE WORKSPACE at query time — list membership is read server-side, so the request never carries member ids. Only real-estate-agent members count; loan officers and manual (unlinked) records on the same list are ignored. mode: "in" with no matching members returns an empty page (not an unfiltered one). Errors: 400 crm_list_requires_workspace when the caller has no active workspace (API-key / OAuth callers must select an organization), 403 / 404 when a named list is not visible to the caller or does not exist, and 400 crm_list_too_large when the selected lists hold more than 50,000 agents in total — narrow the selection rather than get a silently partial answer.
Show child attributesHide child attributes
listsone ofrequiredWhich lists: "any" for every People list the caller can see, or an array of list ids. Membership is the UNION across the selected lists.
Show child attributesHide child attributes
Option 1enumEvery list in the caller's workspace that the caller can see (own, org-wide, or shared with them) and that holds this kind of record — People lists for originators and agents, Company lists for companies.
anyOption 2string[]Specific CRM list ids (1–50).
modeenumrequiredin — only agents who are a member of the selected list(s). notIn — exclude every agent who is a member of the selected list(s); everyone else passes, including agents on none of your lists.
innotInexcludeOfficeGroupsenum[]Drop these brand groups (same gate).
compass_legacyanywherefranchiseothersfiltersone ofShow child attributesHide child attributes
Option 1objectShow child attributesHide child attributes
childrenone of[]requiredArray of filter expressions (AND)
Same shape as its parent.
typeenumrequiredandOption 2objectShow child attributesHide child attributes
childrenone of[]requiredArray of filter expressions (OR)
Same shape as its parent.
typeenumrequiredorOption 3objectShow child attributesHide child attributes
childone ofrequiredSame shape as its parent.
typeenumrequirednotOption 4objectShow child attributesHide child attributes
fieldstringrequiredopenumrequiredComparison 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.
eqneqgtgteltltebetweeninmatchgeoDistanceexiststypeenumrequiredfiltervaluenullComparison value
flatFiltersobjectShow child attributesHide child attributes
activeListingsone of | nullCurrent active listings (not period-scoped). {gte: 1} = has listings.
Show child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumberavgMortgagedLoanAmountone of | nullMean loan size across the agent's financed deals — the price band their buyers actually borrow in.
Show child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumberavgSalePriceone of | nullShow child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumberbuyerUnitsone of | nullShow child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumberbuyerVolumeone of | nullShow child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumbercityone of | nullCity — 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. Cities in several states: write each as "City, ST" (["Springfield, IL", "Austin, TX"]) — each binds to its own state; a bare name plus a state list cross-pairs.
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any value
Option 3objectFuzzy text match
Show child attributesHide child attributes
matchstringrequiredcountyone of | nullCounty, keyed by 5-digit county FIPS code (e.g. 06037 = Los Angeles, CA; 04013 = Maricopa, AZ). By default matches agents who closed transactions in this county (production alone — unlike city/state/zip, which an office address also satisfies); with locationSource: "office" it matches agents whose CURRENT office lies inside the county boundary. 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.
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any of several counties
currentOfficeone of | nullBrokerage/office name(s), OR'd: each a case-insensitive whole-word phrase ("compass" matches "Compass RE", not "Encompass"); end with * for a prefix ("washington fine*"); names with punctuation ("@properties") match as a substring. {match} is a fuzzy single-name match. Matches only the agent's CURRENT office; office takes the same values and matches ANY office on record.
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any value
Option 3objectFuzzy text match
Show child attributesHide child attributes
matchstringrequiredcurrentOfficeKeyone ofOffice roster: agents whose CURRENT office is this office id (the id from listOffices / instantSearch, raw or encoded). Several ids OR.
Show child attributesHide child attributes
Option 1stringOption 2string[]dualUnitsone of | nullShow child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumberdualVolumeone of | nullShow child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumberemailone of | nullEmail address, matched EXACTLY (case and surrounding whitespace normalized). Matches the agent's current email OR any email in their contact history, so an agent is found by an address they used on past transactions. An array matches any.
Show child attributesHide child attributes
Option 1stringOption 2string[]excludeCurrentOfficeone of | nullDrop agents whose CURRENT office matches these names.
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any value
Option 3objectFuzzy text match
Show child attributesHide child attributes
matchstringrequiredexcludeOfficeone of | nullDrop agents with ANY office matching these names (same grammar as office).
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any value
Option 3objectFuzzy text match
Show child attributesHide child attributes
matchstringrequiredfirstNameone of | nullDeprecated: 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.
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any value
Option 3objectFuzzy text match
Show child attributesHide child attributes
matchstringrequiredgeoPointobject | nullRadius search — { lat, lon, radius } (e.g. radius "15mi" or "24km") — around any office on the agent's record; with locationSource office the CURRENT office, production their transactions.
Show child attributesHide child attributes
latnumberrequiredlonnumberrequiredradiusstringrequiredhasEmailbooleanWhether the row's email is populated.
hasPhonebooleanWhether the row's phone is populated.
idone of | nullExact 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.
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any value
Option 3objectFuzzy text match
Show child attributesHide child attributes
matchstringrequiredlastNameone of | nullDeprecated: 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.
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any value
Option 3objectFuzzy text match
Show child attributesHide child attributes
matchstringrequiredlastTransactionDateone of | nullDate of the agent's newest deal inside the selected period — "recently active". {gte: "2026-07-01"}. Only producing agents carry it.
Show child attributesHide child attributes
Option 1stringExact date, or a whole period: YYYY-MM-DD (that day), YYYY-MM (the whole month — "2025-06" = 2025-06-01 through 2025-06-30) or YYYY (the whole year). YYYYMMDD, MM/DD/YYYY, an ISO-8601 datetime and epoch milliseconds are also accepted. An unparseable value is a 400.
Option 2objectDate range. Excludes null/missing-field docs by default; add includeNulls: true to keep them. Bounds accept YYYY, YYYY-MM, YYYY-MM-DD, YYYYMMDD, MM/DD/YYYY, a full ISO datetime or epoch milliseconds; an unparseable bound is a 400. A partial bound denotes the whole period and expands to the edge that preserves the operator: gte/lt take the period START, gt/lte take the period END — so {gte: "2024"} means on/after 2024-01-01 and {lte: "2024"} means through 2024-12-31.
Show child attributesHide child attributes
gtstringgtestringincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires a bound.
ltstringltestringlicenseNumberone of | nullReal-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.
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any of several licenses
licensedSinceDateone of | nullOriginal issue date of a real-estate license on the record (any license) — "new agents": {gte: "2025-10-01"}. Lifetime, not period-scoped; on ~26% of agents.
Show child attributesHide child attributes
Option 1stringExact date, or a whole period: YYYY-MM-DD (that day), YYYY-MM (the whole month — "2025-06" = 2025-06-01 through 2025-06-30) or YYYY (the whole year). YYYYMMDD, MM/DD/YYYY, an ISO-8601 datetime and epoch milliseconds are also accepted. An unparseable value is a 400.
Option 2objectDate range. Excludes null/missing-field docs by default; add includeNulls: true to keep them. Bounds accept YYYY, YYYY-MM, YYYY-MM-DD, YYYYMMDD, MM/DD/YYYY, a full ISO datetime or epoch milliseconds; an unparseable bound is a 400. A partial bound denotes the whole period and expands to the edge that preserves the operator: gte/lt take the period START, gt/lte take the period END — so {gte: "2024"} means on/after 2024-01-01 and {lte: "2024"} means through 2024-12-31.
Show child attributesHide child attributes
gtstringgtestringincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires a bound.
ltstringltestringmodeenumandormodelMatchIdone of | nullAlias of id — the agent's ModelMatch id. Exact match (canonical or since-merged legacy id).
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any value
Option 3objectFuzzy text match
Show child attributesHide child attributes
matchstringrequiredmortgagedBuyerUnitsone of | nullCount of the agent's buyer-side deals that were financed — the sharpest 'how many mortgage introductions can this agent make' number on the record.
Show child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumbermortgagedBuyerVolumeone of | nullDollar 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.
Show child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumbermortgagedDualUnitsone of | nullCount of the agent's dual-agency deals that were financed.
Show child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumbermortgagedDualVolumeone of | nullDollar volume of the agent's dual-agency deals that were financed.
Show child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumbermortgagedSellerUnitsone of | nullCount of the agent's seller-side (listing) deals whose buyer financed.
Show child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumbermortgagedSellerVolumeone of | nullDollar volume of the agent's SELLER-side (listing) deals whose buyer financed.
Show child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumbernameone of | nullDeprecated: 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.
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any value
Option 3objectFuzzy text match
Show child attributesHide child attributes
matchstringrequirednamePrefixstringPrefix name search: every word must start a word of the name ("jen ro" → Jennifer Rodriguez). No fuzzy/nickname matching; relevance-ranked unless sort is set. Max 100 chars / 6 words (emails, URLs, phones ignored), else 400.
officeone of | nullShow child attributesHide child attributes
Option 1stringOption 2string[]Match any value
Option 3objectFuzzy text match
Show child attributesHide child attributes
matchstringrequiredpercentUnitsMortgagedone of | nullShare 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.
Show child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumberpercentVolumeMortgagedone of | nullShare 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.
Show child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumberphoneone of | nullUS phone number, any formatting ((512) 555-0100, 512.555.0100, +1 5125550100) — reduced to its 10 digits. Matches the agent's current direct phone OR any phone in their contact history; office/brokerage lines are not searched. Anything that is not a 10-digit US number is a 400. An array matches any.
Show child attributesHide child attributes
Option 1stringOption 2string[]producersOnlyboolean | nullsellerUnitsone of | nullShow child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumbersellerVolumeone of | nullShow child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumberstateone of | nullState — 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.
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any value
Option 3objectFuzzy text match
Show child attributesHide child attributes
matchstringrequiredtotalCompaniesWorkedWithone of | nullHow many distinct mortgage COMPANIES financed this agent's deals in the selected period.
Show child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumbertotalLendersWorkedWithone of | nullHow many distinct LENDERS financed this agent's deals in the selected period.
Show child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumbertotalOriginatorsWorkedWithone of | nullHow 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.
Show child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumberunitsone of | nullShow child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumbervolumeone of | nullShow child attributesHide child attributes
Option 1numberOption 2number[]Match any value
Option 3objectNumeric range. Excludes null/missing-field docs by default; add includeNulls: true to keep them.
Show child attributesHide child attributes
gtnumbergtenumberincludeNullsbooleanAlso keep docs where the field is null/missing (a range filter drops them by default). Requires at least one of gte/lte/gt/lt.
ltnumberltenumberzipone of | nullZIP — 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.
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any value
Option 3objectFuzzy text match
Show child attributesHide child attributes
matchstringrequiredzipCodeone of | nullAlias of zip — identical behavior. Kept so the zipCode spelling used by loans/sales works here too.
Show child attributesHide child attributes
Option 1stringOption 2string[]Match any value
Option 3objectFuzzy text match
Show child attributesHide child attributes
matchstringrequiredfootprintone ofScoped 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 /v1/agents/{id}/markets (live-aggregated) for an agent's geography.
Show child attributesHide child attributes
Option 1objectShow child attributesHide child attributes
avgLoanAmountobjectDollar 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.
Show child attributesHide child attributes
gtnumbergtenumberltnumberltenumberdimensionenumWhich 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.
zipcitycountystatelenderlenderone ofFinancing 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.
Show child attributesHide child attributes
Option 1stringOption 2string[]notbooleanInvert the whole entry: match agents with NO lender relationship matching it.
productobjectCorrelate a product INSIDE this lender relationship — 'FHA business through this lender'.
Show child attributesHide child attributes
avgLoanAmountobjectDollar 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.
keyone ofProduct key(s), lowercase — e.g. fha, conventional, va for loanType; purchase, refinance for transactionType.
mixenumWhich product breakdown inside the market — loan type (fha, conventional, va, …) or transaction type (purchase, refinance, …).
loanTypetransactionTypeshareOfUnitsobjectDollar 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.
shareOfVolumeobjectDollar 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.
unitsobjectDollar 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.
volumeobjectDollar 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.
unitsobjectDollar 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.
Show child attributesHide child attributes
gtnumbergtenumberltnumberltenumbervolumeobjectDollar 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.
Show child attributesHide child attributes
gtnumbergtenumberltnumberltenumberOption 2object[]Show child attributesHide child attributes
avgLoanAmountobjectDollar 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.
Show child attributesHide child attributes
gtnumbergtenumberltnumberltenumberdimensionenumWhich 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.
zipcitycountystatelenderlenderone ofFinancing 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.
Show child attributesHide child attributes
Option 1stringOption 2string[]notbooleanInvert the whole entry: match agents with NO lender relationship matching it.
productobjectCorrelate a product INSIDE this lender relationship — 'FHA business through this lender'.
Show child attributesHide child attributes
avgLoanAmountobjectDollar 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.
keyone ofProduct key(s), lowercase — e.g. fha, conventional, va for loanType; purchase, refinance for transactionType.
mixenumWhich product breakdown inside the market — loan type (fha, conventional, va, …) or transaction type (purchase, refinance, …).
loanTypetransactionTypeshareOfUnitsobjectDollar 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.
shareOfVolumeobjectDollar 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.
unitsobjectDollar 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.
volumeobjectDollar 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.
unitsobjectDollar 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.
Show child attributesHide child attributes
gtnumbergtenumberltnumberltenumbervolumeobjectDollar 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.
Show child attributesHide child attributes
gtnumbergtenumberltnumberltenumberincludeenum[]Opt-in row blocks.
contactsofficesloanMixlenderFiltersobject[]Show child attributesHide child attributes
canonicalstringCanonical lender name (the value from lender autocomplete). Resolved to a lender id server-side; pass id instead when you have one.
displayNamestringrequiredLabel / typed search string
idstringLender-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.
modeenumincludeexcludepercentMinnumberMinimum percent_of_volume (0–100); 0/undefined = > 0%
typeenumcanonicalfreetextlenderMatchModeenumandorlocationSourceenumWhich location signal city/state/zip/county, geoPoint and near match. any (default) = an office OR a market they transacted in (geoPoint: any office on record); office = their CURRENT office (a bare state also matches the state on their member record; county = the office inside the county boundary); production = transaction markets only.
anyofficeproductionlosOnMyTeamobjectRelationship with loan officers at the CALLER's company, resolved server-side from the caller's profile NMLS id and that LO's current employer; the caller's own deals never count. 400 los_on_my_team_requires_company when the caller has no NMLS id on their profile or it resolves to no company.
Show child attributesHide child attributes
minUnitsintegerBuyer-side deals with ONE colleague that count as a relationship (default 1). Under doesNotWorkWith, agents below it still pass.
relationshipenumrequiredworksWith — the agent's buyers were financed by loan officers at the caller's company; doesNotWorkWith — no such relationship (prospects).
worksWithdoesNotWorkWithnearobject[]Radius search, entries OR'd, on the locationSource points (current office / transactions / either). With city+state an entry also matches addresses in that city beyond the radius.
Show child attributesHide child attributes
citystringlatnumberrequiredlonnumberrequiredradiusstringrequiredstatestringofficeGroupsenum[]Current office in any of these brand groups. Needs the rocket-filter entitlement (else 403).
compass_legacyanywherefranchiseotherspaginationobjectShow child attributesHide child attributes
cursorstringOpaque cursor from previous response for next page
sizeintegerPage size (1-100, default 25)
periodenumPre-aggregated period block. Rolling windows (last30Days, last60Days, last90Days, previousMonth, currentMonth) are NOT accepted here and return 400; they are supported on the loans, sales and market endpoints (list, count, breakdowns, analytics summary / time-series / chart) (see DatedPeriod).
2017201820192020202120222023202420252026last3Monthslast6Monthslast12Monthslast14Monthslast16Monthslast18Monthslast24MonthsyearToDateallTimeproductMixobject[]Agents whose buyers financed with these loan products in the selected period, ANDed: [{product: "fha"}, {product: "va", minShare: 10}]. Not a whole-book share — the index stores product mix per mortgage company only.
Show child attributesHide child attributes
minSharenumberMinimum financed volume of this product through ONE mortgage company, as a percent of the agent's period sale volume. Omit for 'any deal financed with this product'.
productenumrequiredLoan product (case-insensitive). government = FHA, VA or USDA.
conventionalfhavausdagovernmentheheloccommercialbuildingreversesideDominanceenum[]Which side the agent mostly represents in the selected period, OR'd: buyer = more buyer-side than seller-side deals, seller = the reverse (a tie is neither), dual = at least one dual-agency deal.
buyersellerdualsortobject[]city, state, zip and office order by the agent's CURRENT office — the same office each row shows. Agents with no current-office address sort last in both directions, including agents whose state comes only from their license record. The city/state/zip FILTERS are broader: they match any office or any sale location.
Show child attributesHide child attributes
fieldenumrequiredofficecitystatezipvolumeunitsavgSalePricebuyerVolumebuyerUnitssellerVolumesellerUnitsdualVolumedualUnitsnamefirstNamelastNameemailproducersOnlymortgagedBuyerVolumemortgagedBuyerUnitsmortgagedSellerVolumemortgagedSellerUnitsmortgagedDualVolumemortgagedDualUnits+4 moreorderenumascdesccolumnsobject[]A FORMATTED file: its columns, in order, with header labels and number formats — for format csv or xlsx only, and not combined with fields or a push-target destination (400 columns_format_unsupported / columns_with_fields / columns_with_destination). Every field a column reads is gated by the entitlement exactly as if it were listed in fields: a withheld field drops out of a column's fallback list, and a column with nothing left is omitted. An unknown field is a 400 unknown_column_field. No id column is added. A formatted csv starts with a UTF-8 byte-order mark and uses CRLF line endings, so Excel opens it with accented names intact. Columns may read any DTO field and any opt-in column fields documents, including the computed governmentPct, branchCount, managerName / managerNmlsId and licensedSince.
Show child attributesHide child attributes
fieldone ofrequiredThe response DTO field this column reads — the same names fields takes, dotted into nested objects (contact.linkedin) — or a list of them, taking the first non-empty value (["contact.personalEmail", "contact.workEmail", "email"]).
Show child attributesHide child attributes
Option 1stringOption 2string[]formatenumcurrency, number and percentWhole round the value to a whole number (in both csv and xlsx) and, in xlsx, display it as $1,234,567, 1,234 or 62%. percentWhole expects a value that is already 0–100 (it is written as 62 in csv; in xlsx the cell holds 0.62 under the standard percent format, so it displays 62% in every spreadsheet app and calculates as a percent). text writes an xlsx text cell. titleCase (dina verteramo → Dina Verteramo), lowercase, and phone (US 10-digit numbers as (469) 907-7475; anything else as stored) reshape the text and write a text cell. Omit for the value as-is.
currencynumberpercentWholetexttitleCaselowercasephonelabelstringrequiredHeader for the column.
valueMapobjectDisplay text per value, keyed by the value as a string ({ "true": "Branch Manager", "false": "Originator" }, { "BANK": "Bank" }). The key "null" matches an empty value. Unmatched values are written unchanged.
Show child attributesHide child attributes
[key: string]stringdestinationobjectWhere the finished delivery goes. Omit for the default — a file you download from the status endpoint. push-target: when the job completes, the rows are handed to the named push target, which sends them to its configured HTTPS destination using its own field mapping and signing. The target is checked at submit (it must exist, be enabled, accept this entity, and be usable by you on your plan) — a failed check rejects the submit with the push target's error code. format is ignored (the handoff is always gzipped NDJSON), and when the target's mapping reads only some fields, only those fields (plus id) are delivered. Row limits, entitlements, limit, and billing (1 credit / row) are unchanged, except that deliveries submitted from the ModelMatch web app are not billed. Poll the job for pushBatchId; a handoff that cannot be completed fails the job with error push_handoff_failed and is not billed.
Show child attributesHide child attributes
targetIdstringrequiredId of a push target configured on the active workspace (or your own member push targets).
typeenumrequiredpush-targetfieldsstring[]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; marketCount / countyCount / stateCount / zipCount / lenderCount (originators) — the market-breadth rollups you can already filter on; and the computed governmentPct (originators: FHA + VA percent of loans, 0–100), branchCount (companies: NMLS branch count) and managerName / managerNmlsId (branches: the first branch manager) and licensedSince (branches: first-licensed date, the earliest license issueDate, YYYY-MM-DD). Agents also offer email2 / phone2 (the best-ranked email / phone distinct from email / phone, admitted by the email / phone entitlement field), bestEmail / bestEmail2 and bestPhone / bestPhone2 (the best and runner-up contact over every email / phone on the record, email / phone included — the pair the ModelMatch web app's agent export shows; same entitlement fields), officePhone (admitted by phone), activeListings (current active listings; null when unknown), and the profile-link columns facebook, instagram, linkedin, twitter, youtube, tiktok, zillow, otherLinks (a ; -joined list of profile URLs on no known platform) — all admitted by the links entitlement field. Loans offer the list row's transaction-export fields (employerName, employerNmlsId, brokerName, titleCompanyName, soldAgentName, listAgentName, coListAgentName, buyer1FirstMiddle … seller2Last). In csv and parquet the two block columns are JSON-encoded cells; in json and ndjson they are nested objects. Windowed production (originators, agents, companies, branches): name <field>_<n>mo for n in 3, 6, 12, 14, 18, 24 to get a production field for that trailing window regardless of period — e.g. volume_3mo, units_6mo, purchaseVolume_24mo. Available for originators volume, units, avgLoanAmount, purchaseVolume, purchaseUnits, refinanceVolume, refinanceUnits, conventionalPct, fhaPct, vaPct; agents volume, units, avgSoldPrice, buyerVolume, buyerUnits, sellerVolume, sellerUnits, totalOriginatorsWorkedWith, totalCompaniesWorkedWith, totalLendersWorkedWith; companies volume, units, avgLoanAmount, loCount; branches volume, units, avgLoanAmount, purchasePct, refinancePct, loCount. Numbers (null when the window has no data); an entitlement that allows a field allows every window of it.
formatenumOutput 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). xlsx: a single-sheet Excel workbook with a bold, frozen header row — numbers are numeric cells, everything else (ids, zips, phones) text cells (.xlsx). Pair with columns for labelled headers and number formats. Required on submit unless destination is a push target, which always delivers gzipped NDJSON (a missing format on a file delivery is a 400 format_required).
ndjsonjsoncsvparquetxlsxlimitintegerOptional hard cap on the number of rows delivered — and therefore billed (1 credit / row). 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 — 5,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 5,000-row allowance.
Responses
202objectJob queued; ECS task launchedShow attributesHide attributes
billingenumcredits = billed at 1 credit per delivered row. none = not billed (deliveries submitted from the ModelMatch web app).
creditsnonedestinationobjectWhere the finished delivery goes. Omit for the default — a file you download from the status endpoint. push-target: when the job completes, the rows are handed to the named push target, which sends them to its configured HTTPS destination using its own field mapping and signing. The target is checked at submit (it must exist, be enabled, accept this entity, and be usable by you on your plan) — a failed check rejects the submit with the push target's error code. format is ignored (the handoff is always gzipped NDJSON), and when the target's mapping reads only some fields, only those fields (plus id) are delivered. Row limits, entitlements, limit, and billing (1 credit / row) are unchanged, except that deliveries submitted from the ModelMatch web app are not billed. Poll the job for pushBatchId; a handoff that cannot be completed fails the job with error push_handoff_failed and is not billed.
Show child attributesHide child attributes
targetIdstringrequiredId of a push target configured on the active workspace (or your own member push targets).
typeenumrequiredpush-targetentityTypestringrequiredestimatedTotalintegerrequiredformatenumrequiredOutput 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). xlsx: a single-sheet Excel workbook with a bold, frozen header row — numbers are numeric cells, everything else (ids, zips, phones) text cells (.xlsx). Pair with columns for labelled headers and number formats. Required on submit unless destination is a push target, which always delivers gzipped NDJSON (a missing format on a file delivery is a 400 format_required).
ndjsonjsoncsvparquetxlsxjobIdstringrequiredmaxRowsintegerrequiredstatusenumrequiredqueued400one ofValidation failure (incl. `format_required`: a file delivery needs `format`; a refused `columns` request), delivery would exceed the entitlement's maxRows, OR the push target does not accept this entity (`ENTITY_MISMATCH`)401objectAuthentication required402one ofInsufficient credits (balance < estimatedTotal, at 1 credit per row), OR the plan does not include push targets (`PLAN_REQUIRED`)403one ofDelivery exceeds the 5,000-row limit available without the `bulk-delivery.agents` entitlement (lower `limit`, narrow the filters, or contact support for a limit increase), OR you may not use the push target (`FORBIDDEN`), OR a scoped token named a push-target destination without `push-targets:send` (`insufficient_scope`).404objectPush target not found (`TARGET_NOT_FOUND`)409objectPush target is disabled (`TARGET_DISABLED`)502objectPreflight / S3 / DDB / ECS launch failure, the push-target check could not reach the auth server, or the credit balance could not be read (`billing_unavailable` — retry; a paid delivery is never queued unverified)