A good filter is work. Saved filters keep it. Name a search in the app and it’s there next week; save one through the API and it shows up in the app the same minute. Both sides talk to the same endpoint, so a saved filter is a thing you can run, export, push, or hand to an assistant, not a bookmark in one tool.
What gets saved
A saved filter is a small record with everything needed to run it again:
| Field | What it holds |
|---|---|
name, icon | What you see in the list. The icon is a color dot, a tinted icon, or an emoji |
target | Which list it runs against: originators, agents, companies, branches, offices, loans, properties, sales, or a CRM table |
operationId | The exact list operation to call, such as listOriginators |
query | The request body for that operation, minus pagination. Validated on save, so a typo in a field name is rejected rather than silently ignored |
fidelity | exact when the query captures the whole search, partial when the app couldn’t express some of it (see unmapped), ui_only when there’s nothing to run |
stale | True if the API’s contract changed and the query no longer validates. staleIssues says what |
uiState | Opaque state the app uses to restore its filter panel. The API never reads it |
Filters are private to you and capped at 25 per target. A kind: "view" record is a saved CRM table layout rather than a search, with its own quota.
Save one from the API
Send the body you’d send to the list endpoint, without pagination:
curl -X POST https://api.modelmatch.com/v1/saved-filters \
-H "x-api-key: mm_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Austin FHA movers",
"target": "originators",
"icon": { "type": "emoji", "emoji": "🏠" },
"query": {
"flatFilters": { "msa": "12420", "units": { "gte": 24 }, "hasPhone": true, "timeAtCompanyMonths": { "lte": 12 } },
"productMix": [{ "product": "fha", "minShare": 30 }],
"period": "last12Months",
"sort": [{ "field": "scopedVolume", "order": "desc" }]
}
}'With the MCP server connected:
Save that last search as “Austin FHA movers” so I can rerun it.
The assistant calls manageSavedFilter with the body it just ran. From then on, “run my Austin FHA movers filter” is enough.
The response is the saved record with its id. Open the app and it’s in the saved list for loan officers, panel restored from the query.
Run one from the API
Two calls. Get the record, then post its query to the operation it names:
curl https://api.modelmatch.com/v1/saved-filters/qjy2eCHgFBeAwYQdfNvzs \
-H "x-api-key: mm_your_key_here"
{
"data": {
"id": "qjy2eCHgFBeAwYQdfNvzs",
"name": "Long Beach producers",
"target": "originators",
"operationId": "listOriginators",
"fidelity": "exact",
"unmapped": [],
"stale": false,
"query": {
"period": "last12Months",
"filters": {
"type": "and",
"children": [
{ "type": "filter", "field": "city", "op": "eq", "value": "Long Beach" },
{ "type": "filter", "field": "state", "op": "eq", "value": "CA" }
]
}
}
}
}
Before running, check two things. If fidelity is partial, the query omits the keys in unmapped, so results are broader than the app shows. If stale is true, re-save from the app or fix the query first. Then:
curl -X POST https://api.modelmatch.com/v1/originators \
-H "x-api-key: mm_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"period": "last12Months",
"filters": { "type": "and", "children": [
{ "type": "filter", "field": "city", "op": "eq", "value": "Long Beach" },
{ "type": "filter", "field": "state", "op": "eq", "value": "CA" }
]},
"pagination": { "size": 50 }
}'
The same query works unchanged on the target’s count endpoint (free) and its bulk-delivery endpoint, so a saved filter is also a saved export and a saved push.
Keep them current
- Rename or re-icon with
PATCH /v1/saved-filters/{id}. The target is fixed; the query can be replaced and is validated again. - List with
GET /v1/saved-filters, optionally?target=originatorsor?kind=view. - Delete with
DELETE /v1/saved-filters/{id}. - Schedule it. A saved filter plus a bulk export on a cron is a weekly list that lands in your inbox or your CRM without anyone rebuilding the search.