Query search results
query_search_resultsColumns: id, agent_id, entity_type, list_name, source, identifier,
display_name, verdict, verdict_reason, data (JSONB), created_at, person_id,
company_profile_id, linkedin_slug, linkedin_provider_id, email. Filter by list
with "list_name = 'oil-gas'". identifier is the key the row was saved under —
a company's domain; for a person, whichever LinkedIn handle or email its source
had. A person's LinkedIn profile slug, provider id and email are in
linkedin_slug, linkedin_provider_id and email, read from the linked person
('' when the row isn't linked or the person has none). source is the
discovery tool that surfaced the row ('agent' when no discovery tool did;
'legacy' for rows older than the column). verdict is the curation call
recorded on the row with record_search_results, or by the check a search
tool, a post monitor's engager capture or a Websets list runs on the rows it
saves — 'qualified', 'rejected', 'unclear' for a row
screened but too thin to judge, or NULL for a row not yet screened — with
verdict_reason saying why. Rejected rows are left out unless you pass
verdict='rejected', include_rejected or run_id, the same as the user's default
view, so a where_clause on verdict alone never reaches them.
person_id / company_profile_id are the canonical person / company FK ids
(NULL until the row is linked). A person's profile (title, company) and a
company's firmographics (industry, location, employee count, description) — the
values the agent's People and Companies tabs show — live on the linked record, not
in the row's own data: read them with query_people / query_companies on
those ids, and filter on them through the id, e.g. "company_profile_id IN (SELECT
id FROM research_app_company_profiles WHERE industry ILIKE '%oil%')".
For a person's LinkedIn degree and warm-intro connectors, or the agent's people
counted by list, source, company, degree or connector, use list_people instead. For
the agent's companies as its Companies tab shows them, one row per company with its
lists, verdict and signals rolled up across rows, or counted by list or source, use
list_companies.
data has no single schema — its shape follows whichever source wrote the
row (it is the agent-authored blob). Most person rows nest under person
(data->'person'->>'position',
data->'person'->'company'->>'name') and most company rows under company
(data->'company'->>'name'), but other sources
write those fields flat. A path that doesn't exist yields NULL rather than
an error, and a NULL comparison drops the row — so a filter aimed at the
wrong shape comes back empty or short and reads as a genuine miss. Read a
page of rows without a data filter first, then filter against the shape
you see.
Person rows are annotated with the team connection overlay (mirrors the Find
UI): a matched row's data gains connection_status: {you: bool, teammates: [{email, name, first_name}]} naming the viewer/teammates who are 1st-degree
to that prospect; unmatched rows and company rows carry no such key. A
top-level connections_coverage: {you: 'none'|'partial'|'csv_uploaded', team_missing: int} reports the owner's own connection coverage and how many
active teammates still lack a CSV upload. The viewer is the agent owner.
A dict with count, truncated, and items array (each row {id, agent_id,
entity_type, list_name, source, identifier, display_name, verdict,
verdict_reason, data, person_id, company_profile_id, linkedin_slug,
linkedin_provider_id, email, columns, created_at}), plus connections_coverage
{you, team_missing}. columns is the normalized [label, value] projection of
the row's agent-researched data.columns.
Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"agent_id": "<agent_id>"
},
"name": "query_search_results"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum results (default 50, max 200). | |
| offset | No | Rows to skip for paging (default 0). When the result is truncated, re-call with offset += limit for the next page. | |
| run_id | No | Only the rows whose person or company this search run returned, rejected ones included, on the list it saved to (an `id` from `query_search_runs`). Omit for every row. | |
| verdict | No | Only the rows with this verdict, 'qualified', 'rejected' or 'unclear' ('rejected' reads the rows the user's default view filters out). Omit for every verdict. | |
| agent_id | Yes | Filter to a specific agent (required). | |
| order_by | No | SQL ORDER BY (default: created_at DESC). | created_at DESC |
| on_behalf_of | No | A teammate's email, or an agency client's from list_agency_clients, to run this call in that account: their agents, settings, connected accounts, and credits. Omit it to act on your own account. | |
| where_clause | No | SQL WHERE condition (default returns all rows for the agent). Examples: "data->'person'->>'position' ILIKE '%VP%'", "entity_type = 'person'", "list_name = 'oil-gas-operators'". | 1=1 |
| include_rejected | No | Also return the rows marked rejected. Default False. |