Narrow the list to records whose name, email or company contains this text — anywhere in it, ignoring case. For a branch, "name" is the branch's own name; the row carries no person.
The text is matched literally: % and _ are not wildcards, so 50% finds a company containing "50%" and a_b finds "a_b". There is no wildcard, prefix or exact-match mode.
Filtering happens before paging, so meta.pagination.total is the number of matches, not the size of the directory. A term that matches nothing is a normal empty result — 200 with an empty data and total: 0 — not an error. Leaving it out, or sending an empty string, applies no filter at all and returns everything.
Which fields are matched, per list: brokers and loan officers — first name, last name, email, company; branches — branch name, company, contact email, and the branch manager's first and last name; back-office employees — first name, last name, email. The rule is every identity column the resource has, not every column its list row shows.
⚠️ A matched branch may show nothing that explains the match. Three of those five branch fields — the contact email and the two manager names — are on GET /api/v4/branches/{id}, not in the list row. So search=Robert can return a branch whose branchName, companyName, city and state contain no "Robert". That is correct: fetch the branch by its id to see why it matched. Searching only the list fields was the worse option — a branch you can find by its manager through the detail endpoint would be unfindable from the list.
Longer than 255 characters is a 422, not a silent empty list.