Instant Search

Fast typeahead lookups across agents, originators, companies, and offices — call the route directly, or mint a scoped token and query the search host yourself.

Instant Search is a fast typeahead/autocomplete lookup across agents, originators, companies, and offices. Give it a few characters of a name and it returns the top matches per entity type — built for "search-as-you-type" boxes, not for filtered analytical queries.

There are two ways to use it:

  1. Call the routePOST /v1/instant-search with your API key. Simplest path; the API queries the search backend for you and returns grouped results. Best for server-side code.
  2. Mint a scoped tokenGET /v1/search-token returns a short-lived token plus the host to hit, so a trusted client can query the search indexes directly with per-query controls. Best for browser/client typeahead where you want sub-100ms round-trips without proxying every keystroke through your server.

For filtered, sorted, paginated searches (e.g. "all CA purchase loans over $500k"), use the entity list endpoints instead. Instant Search is for quick name lookups only.

Option 1 — Call the route

Send a POST to /v1/instant-search with your query. Authenticate exactly like any other endpoint — an x-api-key header or a Bearer token (see Authentication).

curl -X POST https://api.modelmatch.com/v1/instant-search \
  -H "x-api-key: mm_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "wells fargo",
    "limit": 5
  }'

The response groups matches under results, keyed by entity type:

{
  "results": {
    "originators": [
      { "id": "123456", "firstName": "Jane", "lastName": "Doe", "...": "..." }
    ],
    "companies": [
      { "id": "789012", "name": "Wells Fargo Bank, N.A.", "...": "..." }
    ],
    "agents": [],
    "offices": []
  }
}

Each entry carries the identifying fields for that entity (id, name, location) — enough to render a result row and then fetch the full record with the matching get* endpoint.

Request fields

FieldTypeDefaultDescription
querystringRequired. The search text (min 1 character).
entitiesstring[]allLimit the search to specific entity types, e.g. ["originators", "companies"].
limitnumber5Max results per entity type (1–50).
filtersobjectPer-entity filter strings, e.g. { "originators": "state = CA" }.
curl -X POST https://api.modelmatch.com/v1/instant-search \
  -H "x-api-key: mm_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "smith",
    "entities": ["originators"],
    "filters": { "originators": "state = TX" },
    "limit": 10
  }'

Option 2 — Mint your own search token

If you're powering a typeahead in the browser, proxying every keystroke through your backend adds latency. Instead, mint a scoped search token and let the client query the search host directly.

GET /v1/search-token (authenticated with your API key) returns a token, the host to query, and the indexes the token is allowed to search:

curl https://api.modelmatch.com/v1/search-token \
  -H "x-api-key: mm_your_key_here"
{
  "token": "eyJhbGciOiJIUzI1NiJ9...",
  "host": "https://search.modelmatch.com",
  "indexes": ["agents", "originators", "companies", "offices"],
  "expiresAt": "2026-06-25T18:40:00.000Z"
}
FieldDescription
tokenShort-lived, scoped search token. Safe to hand to the browser.
hostThe search host to send queries to.
indexesThe index names this token is allowed to search.
expiresAtISO-8601 expiry. Mint a fresh token before this passes.

Tokens are short-lived (minutes), by design. Always read expiresAt rather than assuming a fixed lifetime, and mint on demand — typically once per page load or session. Don't try to cache one long-term. Because the token is scoped to read-only search on these indexes, it's safe to expose to client-side code; your mm_ API key is not and must stay server-side.

Querying the host directly

The search host speaks a standard REST search API, so you query an index with POST {host}/indexes/{index}/search, passing the minted token as a Bearer credential:

curl -X POST https://search.modelmatch.com/indexes/originators/search \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "q": "jane smith",
    "limit": 5,
    "attributesToSearchOn": ["firstName", "lastName"]
  }'

The host returns a standard result envelope:

{
  "hits": [
    {
      "id": "123456",
      "firstName": "Jane",
      "lastName": "Smith",
      "states": ["CA"],
      "cities": ["Los Angeles"]
    }
  ],
  "query": "jane smith",
  "limit": 5,
  "estimatedTotalHits": 1
}

attributesToSearchOn is the main reason to query directly — it restricts matching to specific fields (e.g. name-only) per request, which the route doesn't expose. Other standard search parameters (filter, offset, attributesToRetrieve, attributesToHighlight, …) work too, scoped to what the token allows.

Mint the token on your server and pass only the host + token to the browser — never the mm_ key.

Which approach should I use?

Call the routeMint a token
EndpointPOST /v1/instant-searchGET /v1/search-token → query host directly
Auth on the wiremm_ API keyScoped, short-lived token
Safe in the browser?No — key would be exposedYes
Multi-entity in one callYes (grouped results)One index per query
Per-field controlNoYes (attributesToSearchOn, filters)
Best forServer-side lookups, scriptsClient-side typeahead

Errors

Both endpoints return the standard authentication errors (401, 403, 429). In addition:

StatusMeaning
400Validation error — e.g. an empty query.
503Search backend is not configured or temporarily unavailable.

When querying the host directly, a 401/403 usually means the token has expired — mint a fresh one from /v1/search-token and retry.

On this page