People Search API: Exact Match vs Text Search
By Kooperativa Engineering
The most common integration mistake we see with people search filters is not a malformed request, it is a request that returns zero results with no error, because one field is being treated as a text search when it is actually an exact match.
first_name and last_name filters are exact matches. Send "Rob" against a profile whose first name is stored as "Robert" and you get nothing back, not a partial match, not a fuzzy match, nothing. full_name, by contrast, is a genuine text search, and it behaves differently in a specific way worth knowing.
How the text-search fields actually match
For full_name and title, the last word in the query is treated as a prefix rather than a whole word. That means "engin" matches both "engineer" and "engineering", which is useful, but it also means multi-word queries require every word to be present somewhere in the field. "chief marketing officer" will not match a profile whose title is just "marketing manager", because "chief" and "officer" are both missing.
A filtered search request
Combining several filters at once looks like this. Location has to be an ISO 2-letter country code, not a full country name, which is the second most common source of an empty result set:
curl -X POST "https://kooperativa.io/api/v1/people/search" \
-H "Authorization: Bearer ik_live_..." \
-H "Content-Type: application/json" \
-d '{
"title": "engineer",
"location": ["US", "GB"],
"seniority": "manager",
"industry": "Computer Software",
"skills": ["Leadership"],
"per_page": 50
}'Filters that are exact even though they look like free text
skills, past_company, and education all match a whole stored value rather than a substring. A profile whose only listed skill is "Leadership Development" will not match a filter for "Leadership", because those are two different stored strings, not one string containing the other.
This is a deliberate tradeoff, not an oversight: exact matching on these fields keeps a search for a specific skill from accidentally pulling in every tangentially related one. The cost is that it requires knowing the exact value as stored, which is rarely obvious in advance for fields like skills or education.
The practical fix
When a filter has an ID variant available, company_id instead of company, education_id instead of education, prefer it. Names drift across profiles ("NYU" versus "New York University" for the same school), IDs do not. company_id comes back on every enrich response, so the pattern that avoids this whole class of bug is: enrich once, cache the ID, filter by ID from then on.
Get started
Try Kooperativa
One API key. Person and company enrichment, structured search, and monitors under one flat license.
