Skip to main content
POST
Search persons using SQL query

Query Format

Write a SELECT * FROM people WHERE ... query. Do not include LIMIT or OFFSET clauses in the SQL — use the limit and offset parameters instead.

Response Shape

  • matches — capped at the request’s limit (max 100).
  • total — the full row count matching your WHERE clause across the database, not just the returned page. Useful for TAM-style sizing: query for “VPs of Engineering at fintech in NY” with limit: 1 and total tells you how many candidates exist. The companion Total-Count-Status response header tells you how total was derived: exact (the true count — selective queries like the one above), estimate (on broad, low-selectivity queries the exact count exceeds its time budget, so total becomes the query planner’s row estimate — treat it as a magnitude, e.g. render “~140,000”, not a precise number), or page (neither available; total is just the returned page size). Search responses do not include match_metadata (that field is only populated by /person/enrich, where there’s a single input identifier to match against). A broad query returns the same response shape with an approximate total, flagged by the header:

Pagination

To page through results beyond the first 100, set offset to the number of rows to skip. Maximum offset is 10,000.
Ordering is deterministic within a build — the same request returns the same rows in the same order, so paged requests don’t overlap or skip rows. Builds run on a periodic cadence; ordering may change across builds, so paginate within a single client session, not across days.

Available Columns

Text Columns

Use ILIKE for partial matching or = for exact matching.

Numeric Columns

Enum Columns

Use = or IN for exact matching.

Boolean Columns

Cross-Table Columns

These columns search across related tables and are automatically rewritten to subqueries:

Example Queries

Authorizations

API-Key
string
header
required

Body

application/json

Request model for SQL query-based person search.

query
string
required

SQL query to execute (must not contain LIMIT clause). Must be a SELECT query only.

Required string length: 1 - 10000
limit
integer
required

Maximum number of results to return (replaces LIMIT in query)

Required range: 1 <= x <= 100
offset
integer
default:0

Number of results to skip for pagination (0-10000). Stable within a build; ordering may change across builds.

Required range: 0 <= x <= 10000
titlecase
boolean
default:false

If true, format text fields in title case (names, job titles, company names, locations, skills, headlines). Raw fields, IDs, URLs, codes, and confidence fields are excluded.

include_fields
string | null

Comma-separated list of fields to include in response. If omitted, all fields are returned.

exclude_fields
string | null

Comma-separated list of fields to exclude from response. Applied after include_fields filter.

pretty_print
boolean
default:false

If true, pretty-print JSON response with indentation.

Response

Success - query executed and results returned

Multiple person matches response.

matches
PersonMatchResponse · object[]
required

List of matches sorted by confidence (descending). Capped at the request's limit.

total
integer
required

For /person/search and /person/discover, the total number of rows matching the query's WHERE clause across the database (not just this page). For /person/enrich, the number of matches found for the input identifier. On search/discover, if the exact count exceeds its time budget (broad, low-selectivity queries) it falls back to the query planner's row estimate, and if that is unavailable, to the size of the returned page; the response header Total-Count-Status reports which (exact, estimate, or page).