Search Companies
Search the company index with filters and a free-text query. Returns matching companies, a total count, facet aggregations, and a cursor for pagination.
Authentication#
Requires a token with the read scope, sent as Authorization: Bearer cornect_….
Request#
Body parameters (all optional):
| Name | Type | Required | Description |
|---|---|---|---|
query | string | No | Free-text search across company name + description. |
countries | string[] | No | Full country names to include — e.g. "Germany", "United States", "United Kingdom". Not ISO codes: "DE" / "US" / "USA" match nothing. Matched exactly and case-sensitively: "united states" also matches nothing. |
states | string[] | No | States/regions to include (full names, same convention as countries). |
cities | string[] | No | Cities to include. Not country-scoped on their own — also set countries to avoid matching same-named cities elsewhere (e.g. Berlin, Germany vs Berlin, Connecticut). |
industries | string[] | No | Industry labels to include. |
exclude_industries | string[] | No | Industry labels to EXCLUDE (must_not). Companies in any of these industries are removed. Coexists with industries. |
naics_codes | string[] | No | Specific 6-digit NAICS codes. |
naics_sectors | string[] | No | Whole NAICS 2022 sectors, matched by code prefix. See below. |
technologies | string[] | No | Detected technologies the company uses. |
technology_categories | string[] | No | Technology categories. |
employee_count_min | integer | No | Minimum employee count, inclusive. See the note on band markers below — 5001-9999 matches nothing. |
employee_count_max | integer | No | Maximum employee count, inclusive. With min this is ONE contiguous range. |
employee_bands | integer[] | No | Company sizes as band markers. The only way to select non-adjacent sizes. See below. |
founded_year_min | integer | No | Earliest founding year. |
founded_year_max | integer | No | Latest founding year. |
keywords | string[] | No | Keyword filters (phrase-match on name + description, OR across chips). |
exclude_keywords | string[] | No | Keywords to EXCLUDE (must_not, same name+description match). A company matching ANY excluded keyword is removed. |
connections | object[] | No | “Has connection” filters. Each entry is {category?, connected_company_id?, connected_domain?} and matches companies that have a connected company as that category (e.g. {"category":"vendor","connected_domain":"salesforce.com"} → companies that have Salesforce as a vendor). Category is one of vendor, investor, partner, integration, customer, parent, holding. Fields within an entry must match the same connection; multiple entries are AND'd. Max 10. |
sort_by | string | No | relevance (default) | quality | employee_count | founded_year | name. See below — "relevance" means two different things. |
sort_order | string | No | asc or desc (default desc). |
cursor | string | No | Opaque pagination cursor from a prior response's next_cursor. |
Response#
{
"items": [
{
"company_id": "a0383c53-8142-5e7c-8ca3-9980289a3ccc",
"name": "Acme Inc.",
"domain": "acme.com",
"industry": "Software",
"employee_count": 320,
"country": "United States",
"city": "San Francisco",
"technologies": ["aws", "stripe"],
"founded_year": 2014
}
],
"total": 4213,
"aggregations": { "industries": [ /* facet counts */ ] },
"next_cursor": "eyJvZmZzZXQiOjI1fQ"
}Company size is a band, not a headcount#
employee_count does not hold a company's actual headcount. Every company carries one of nine values, each standing for a LinkedIn size band:
| Stored value | Band | Companies |
|---|---|---|
1 | 1 | 1,685,257 |
10 | 2–10 | 9,434,274 |
50 | 11–50 | 4,646,803 |
200 | 51–200 | 1,451,923 |
500 | 201–500 | 520,099 |
1000 | 501–1000 | 157,140 |
5000 | 1001–5000 | 124,153 |
10000 | 5001–10000 | 25,807 |
10001 | 10001+ | 35,756 |
A filter of employee_count_min: 5001 with employee_count_max: 9999 matches zero companies — not because none are that size, but because no company stores a value in that interval. Filter on the nine values above, or use employee_bands.
employee_count_min and employee_count_max are ANDed into a single contiguous range, so non-adjacent sizes cannot be expressed with them — “micro-businesses and enterprises, nothing between” has no min/max form. employee_bands takes the set directly:
{ "employee_bands": [1, 10001] }What “relevance” sorts by#
sort_by=relevance is the default, and it is two orderings wearing one name — because what counts as relevant depends on whether you asked a question.
| Request | Ordered by |
|---|---|
with a `query` | Text match score against name (boosted), description, industry and domain. |
without a `query` | data_quality_score — how many of twelve fields the record has filled in. |
data_quality_score counts filled-in fields, so it has only twelve possible values across the whole index and the top bucket holds roughly two million companies. Ordering within a bucket falls through to a stable company id and carries no meaning. Paging deeper into a filter-only search is not walking a ranked list.
quality is that same completeness ordering, applied whether or not a query is present — use it when you want the most complete records for a text search rather than the best-matching ones. relevance is unchanged and keeps its meaning for existing callers.
employee_count, founded_year and name sort on the field itself. Records missing that field sort last in both directions, so sort_order=asc does not fill the first page with blanks.
NAICS: sectors vs codes#
naics_codes filters on specific 6-digit codes. naics_sectors filters on a whole sector and is what you want for sector-level questions: a 6-digit code begins with its sector’s 2-digit prefix by construction, so the sector match covers every code in it — including codes this API has never listed, and codes a future NAICS revision adds.
{ "naics_sectors": ["31-33", "21"] }Three sectors span more than one 2-digit prefix — Manufacturing (31, 32, 33), Retail Trade (44, 45) and Transportation and Warehousing (48, 49). Send the hyphenated code: "31" is a valid NAICS prefix but not a sector, and is rejected rather than quietly searching a third of Manufacturing. An unknown sector returns 422 listing all twenty valid values.
The two filters union: sending both returns companies matching either, not the (usually empty) intersection.
A value outside the nine returns 422 naming the offending entries and listing the valid set, rather than a 200 with no results and no explanation. Counts above were measured on 2026-08-13 and will drift; the nine values are the contract.
Code samples#
curl -X POST https://api.cornect.io/api/v1/companies/search \
-H "Authorization: Bearer cornect_your_token_here" \
-H "Content-Type: application/json" \
-d '{"query":"fintech","countries":["United States"],"employee_count_min":50,"exclude_industries":["Staffing and Recruiting"],"exclude_keywords":["consulting"],"connections":[{"category":"vendor","connected_domain":"salesforce.com"}]}'Errors#
See Errors for the full table. Codes you're most likely to see here:
| Code | Status | When |
|---|---|---|
INSUFFICIENT_SCOPE | 403 | A token without read scope (shouldn't occur — read_write includes read). |
| — | 429 | Rate limit exceeded (60/min). |