Welcome to the People API
The People API is ICP-style people discovery across Signalbase’s signal-driven dataset. Filter by title, function, seniority, geography, and company attributes to build a target list — and every person you get back arrives with amatched_signal inline (a funding round, acquisition, or job change) that tells you why now: the timing reason to reach out, not just who matches your ICP.
This is not a static contact database. People whose company has no active signal within the requested window are excluded by design. It is also a search endpoint — it reads existing records and never triggers the enrichment pipeline.
You can also use it as a precise lookup rather than an ICP browse: pass an identifier — a person’s linkedin_url, or a company_domain / company_linkedin_url — to resolve a specific record and return its people with their signals. See Identifier Lookup below.
Search People Endpoint
View the complete OpenAPI specification
Why now: matched_signal and is_latest_signal
Every result includes a matched_signal — the latest signal that matched your filters. Because Signalbase filters first and then surfaces the latest matching signal, matched_signal is always consistent with your query, but it is not necessarily the person’s newest overall signal.
The is_latest_signal boolean tells you which case you’re in:
true— the matched signal is also the person’s most recent signal.false— an older signal matched your filters, and the person has a more recent signal that did not match.
signal_type, matched_signal is the person’s newest qualifying signal of any supported type (funding_round, acquisition, job_change), so types can mix across a page. Pass signal_type to pin the surface to specific type(s).
Identifier Lookup
Instead of browsing an ICP, you can resolve a specific person or company and return its people with their signals. Any of these identifiers matches the source record by canonical (exact) equality — all accepted URL variants (scheme,www., trailing slash) are normalized before matching:
All-time by default. When any identifier is set,
signal_date_range defaults to all-time rather than 12m — a lookup means “everything on record for this person/company”, not “matched something in the last 12 months”. Pass signal_date_range explicitly to still narrow the window.
Behavior. Invalid identifier syntax returns 400. A valid identifier that resolves to nothing returns an empty data set with a 200. Identifiers AND with any other filters you pass.
Count Mode
You can get the total number of people matching any filter combination without consuming credits by addingcount=true to your request. This returns an empty data array with full pagination metadata, including totalCount.
Key Features
- Signal-backed results: Every person carries a
matched_signalexplaining the timing to reach out - Taxonomy-aware filters: Filter by title, function, and seniority with word-boundary matching (no
COO→Coordinatorfalse positives) - Company targeting: Narrow by company size band and industry
- Geography: Filter by country (person or company), person-only country (
person_countries), and city (job-change people) - Flexible lookback: Control the signal window with
signal_date_range(e.g.30d,6m,2y) - Pagination support: Up to 100 results per page
- Credit-based usage: Transparent credit consumption per API call, with a free count mode
How Filtering Works
- Different filters AND together; comma-separated values within one filter OR together. For example,
seniority=c_level,vp&country=USreturns people who are (C-level OR VP) AND in the US. - A person qualifies if any of their signals matches the filters; the latest matching one is surfaced as
matched_signal. - Results merge two sources (current company employees and job-change subjects) and are deduplicated before pagination by normalized person LinkedIn URL, falling back to normalized name + company domain/LinkedIn/name.
- Default sort:
matched_signal.datedescending (most recent why-now first).
Source-dependent Fields
Some fields are only populated from one of the two underlying sources:Active vs. Former
The endpoint is currently active-only (current employees).include_former=true returns a 400 because job-change records have no current/former semantics yet, so honoring the flag would silently mix records. Until that data dependency is defined, every result has status: "active".
Privacy
Person names are masked in responses (first name + last initial, e.g.Sarah K.), consistent with the Job Change and Employees endpoints. Use linkedin_url to identify a specific person.
Authentication
All API endpoints require a Bearer token in theAuthorization header.
Query Parameters
Parameter names are validated strictly: an unrecognized query parameter returns a
400 listing the supported names. Spellings from the signal endpoints get a pointer to the equivalent here — e.g. countries → country, team_size → company_size, type → signal_type, person_country → person_countries. Previously unknown names were silently ignored, so a typo’d filter returned the full unfiltered dataset.Pagination
Person Filters
Geography
Company Filters
Identifier Lookup
Resolve a specific person or company instead of browsing an ICP — see Identifier Lookup. Setting any of these defaultssignal_date_range to all-time.
Signal Filters
Active / Former
Count Mode
Enum Values
FunctionsResponse Structure
Each result includes the person, their company,is_latest_signal, and the inline matched_signal:
Error Handling
The API returns standard HTTP status codes:- 200: Success
- 400: Bad request — invalid filter value (unknown
function/seniority/company_size/signal_type, malformedsignal_date_range,include_former=true, or invalid identifier syntax inlinkedin_url/company_domain/company_linkedin_url). Note: a valid identifier that resolves to no records returns200with an emptydataset, not400 - 401: Unauthorized — invalid or missing API key
- 402: Insufficient credits
- 429: Rate limit exceeded
- 500: Internal server error
