---
title: "Run a company search"
method: POST
path: "/business/companies/search"
tags: ["Company search"]
---

# Run a company search

`POST /business/companies/search`

## Request

- Base URL: `https://api.tryfuse.ai/api/v1`
- URL: `https://api.tryfuse.ai/api/v1/business/companies/search`
- Auth: HTTP basic

The company twin of the people search. The filter source is exactly one of: literal `filters`, a stored COMPANY saved search (`savedSearchId` / `savedSearchName`), or a natural-language `query` (converted into filters server-side; criteria it could not map come back as `unresolvedCriteria`). A people saved search answers 422 SAVED_SEARCH_TYPE_MISMATCH.

The response always echoes the RESOLVED `filters`. Page by re-sending the same filter source together with the returned `nextCursor` as `cursor`; `nextCursor` is null on the last page. `total` is the true match count and is only counted on the FIRST page — every cursor page answers `total: null`, so read the count once and carry it.

Rows are the provider's company record (snake_case, ~80 fields, varying by company: names, domains, LinkedIn metadata, industries, NAICS codes, headcount and revenue estimates, funding, technologies, headquarters location) plus Fuse's `isSaved`, which says whether the company is already in one of your company lists.

`filters.headquartersCity` names are geocoded one by one and the resulting city areas are OR-ed together; a name that geocodes to nothing is dropped and the search runs on the rest, so take the values from GET /companies/autocomplete?field=location. Only when not one name resolves is the search refused with 422 CITY_FILTER_UNRESOLVED. `employeeCountV2` is the one range whose lower bound is exclusive: `{ min: 50 }` matches companies with more than 50 employees.

Billing: 2 credits per requested company are pre-checked and 2 credits per company returned are debited.

Errors:
- `402` `INSUFFICIENT_CREDITS` — The balance does not cover the pre-check for this request; nothing was billed.
- `404` `SAVED_SEARCH_NOT_FOUND` — No saved search of yours has that id or exact title.
- `409` `SAVED_SEARCH_NAME_AMBIGUOUS` — Two of your saved searches share that title — reference it by `savedSearchId` instead.
- `422` `VALIDATION_FAILED` — The request failed the declared schema; `param` names the offending key and `message` quotes the rule it broke.
- `422` `SAVED_SEARCH_TYPE_MISMATCH` — The saved search exists but stores the other kind of filters; `param` is `savedSearchId`.
- `422` `SAVED_SEARCH_INVALID` — The STORED filters no longer form a runnable company search — the blob is empty, or every value in it was retired. A filterless stored search is refused here rather than run as a whole-universe search.
- `422` `QUERY_FILTERS_INVALID` — The natural-language `query` produced no usable filter; name concrete criteria.
- `422` `CITY_FILTER_UNRESOLVED` — NOT ONE of the `filters.headquartersCity` names geocoded to a city area, so the search was refused rather than run worldwide; names that do geocode are OR-ed together and a name that does not is dropped, so this fires only when every name fails. `param` is `filters.headquartersCity`.
- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.
- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.

Requires one of the following token scopes: companies.

## Request body

- object: Exactly one filter source — `filters`, `savedSearchId`, `savedSearchName` or `query` — plus optional paging.
  - `filters` object: Literal filters, one of the four filter sources. Company filters in the search vocabulary: include/exclude fields take `[{ status, value, label }]` entries (`label` is required), list fields arrays of strings, ranges `{ min, max }` and date ranges `{ start, end }` — enum vocabularies come from GET /companies/filter-options, names and places from GET /companies/autocomplete. Must contain at least one non-empty value.
    - `nameLike` string[]: Free text: company-name fragments of at most 500 chars each, matched fuzzily against the company NAME only (never the description). Several fragments are OR-joined (provider `nameLike.anyOf`); resolve a real company to its canonical name with GET /companies/autocomplete?field=company.
    - `domains` string[]: Free text: company website domains (e.g. stripe.com). A scheme, a www. prefix, a path and the letter case are all stripped before the search, so https://www.Stripe.com/pricing and stripe.com behave the same; a value that is not a domain at all is dropped. Several domains are OR-joined.
    - `keywords` string[]: Free-text keywords matched against company names and descriptions; any may match.
    - `status` object[]: Operating-status entries whose `value` is one of exactly: active, acquired, closed. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`). The provider ignores an exclude list on this field, so an exclusion is sent as the statuses that were NOT excluded, which also drops companies whose status is unknown. This filter ANDs with the others.
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `tags` object[]: Company-tag entries whose `value` is a slug from `companyTags` in GET /companies/filter-options: raised-from-top-vc, venture-backed-startup, is-government, is-school. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others.
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `industriesV2` object[]: Industry entries whose `value` is one of the `fiberIndustries` values in GET /companies/filter-options, copied exactly as listed (e.g. Software, Finance). An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others.
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `linkedinIndustries` object[]: LinkedIn-industry entries whose `value` is one of the `linkedinIndustries` values in GET /companies/filter-options, copied exactly as listed (e.g. Software Development) — a much finer taxonomy than `industriesV2`. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others.
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `crunchbaseCategories` object[]: Crunchbase-category entries whose `value` is one of the `crunchbaseIndustries` values in GET /companies/filter-options, copied exactly as listed (e.g. Financial Services). An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others.
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `crunchbaseCategoryGroups` string[]: Crunchbase category groups as plain strings copied verbatim (case-sensitive) from `crunchbaseCategoryGroups` in GET /companies/filter-options (e.g. Financial Services) — the broad parent of `crunchbaseCategories`. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Several groups are OR-joined (provider `anyOf`); this filter has no exclude form.
    - `naicsCodes` object[]: NAICS entries whose `value` is the code, not the title (`naicsCodes[].code` in GET /companies/filter-options, e.g. 513210 for Software Publishers; 2- to 6-digit codes are all accepted, a shorter code being the broader sector). An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others.
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `headquartersCountryCode` object[]: Headquarters-country entries whose `value` is the country's three-letter `apiCode` from `countries` in GET /companies/filter-options (e.g. USA, DEU). The two-letter `isoCodeAlpha2` in the same row (US, DE) is NOT accepted — the provider rejects it and the whole search fails. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others.
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `headquartersStateName` object[]: Headquarters state/province entries whose `value` is the full state or province name (e.g. Florida, California).
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `headquartersCity` string[]: Up to 25 fully qualified place names from GET /companies/autocomplete?field=location (e.g. Dallas, Texas, United States); each is geocoded independently to its city bounds and the areas are OR-ed together (no exclusion). A name that geocodes to nothing is dropped and the search runs on the names that did resolve — take the values from the typeahead so every one of them counts — and only when NOT ONE of them resolves is the search refused rather than run worldwide (422 CITY_FILTER_UNRESOLVED).
    - `employeeCountV2` object: Headcount range `{ min?, max? }`; any whole number is taken on either side and is used as sent — the values the search UI offers (1, 10, 50, 200, 500, 1000, 5000, 10000) are its own vocabulary, not a constraint here. The lower bound is EXCLUSIVE and the upper bound inclusive, so `{ min: 50 }` matches companies with MORE than 50 employees, and `{ min: 300, max: 320 }` matches 301 to 320. Inverted bounds are read the other way round, and an equal pair keeps only the lower bound, because the provider rejects a range whose bounds meet.
      - `min` number: Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field).
      - `max` number: Inclusive upper bound.
    - `revenueUSD` object: Estimated annual revenue range `{ min?, max? }`; the accepted values are whole US dollars, not millions (5000000 means $5M), and both bounds are inclusive.
      - `min` number: Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field).
      - `max` number: Inclusive upper bound.
    - `totalFundingUSD` object: Total funding raised range `{ min?, max? }`; the accepted values are whole US dollars, not millions (5000000 means $5M), and both bounds are inclusive.
      - `min` number: Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field).
      - `max` number: Inclusive upper bound.
    - `lastFundingUSD` object: Size range of the most recent funding round `{ min?, max? }`; the accepted values are whole US dollars, not millions (5000000 means $5M), and both bounds are inclusive.
      - `min` number: Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field).
      - `max` number: Inclusive upper bound.
    - `stage` object[]: Funding-stage entries whose `value` is one of exactly: pre_seed, seed, series_a, series_b, series_c, series_d, series_e, series_f, series_g, series_h, series_i, series_j, public, acquired, closed, private_equity, venture_other, no_funding_yet, unknown. No endpoint serves this list — it is fixed here. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others.
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `technologies` object[]: Technology-in-use entries whose `value` is a name from the provider's predefined technology vocabulary, forwarded verbatim, so it must carry the product's own spelling and casing — e.g. Salesforce, Kubernetes, Next.js, Google Analytics, and `AWS` for Amazon Web Services. No endpoint serves this vocabulary yet; the product's own picker offers a curated 141-name subset. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others.
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `investors` object[]: Investor entries whose `value` is the investor's website domain — resolve names with GET /companies/autocomplete?field=company&orgType=investor and send the `domain` from that response, never the investor's name. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others.
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `foundedOn` object: Founding-date range `{ start?, end? }` as ISO-8601 dates.
      - `start` string: Earliest date, ISO-8601 (e.g. 2020-01-01).
      - `end` string: Latest date, ISO-8601 (e.g. 2024-12-31).
    - `lastFundedOn` object: Date range of the most recent funding round, `{ start?, end? }` as ISO-8601 dates.
      - `start` string: Earliest date, ISO-8601 (e.g. 2020-01-01).
      - `end` string: Latest date, ISO-8601 (e.g. 2024-12-31).
    - `acceleratorsV2` object[]: Accelerator entries whose `value` is the `acceleratorSlug` from `accelerators` in GET /companies/filter-options (e.g. ycombinator, techstars); the `acceleratorName` in the same row is NOT accepted. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others.
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `fortuneRankings` object[]: Fortune-list entries whose `value` is one of exactly: fortune-500, fortune-1000 (fortune-1000 contains fortune-500). Any other value is silently DROPPED and the whole filter disappears, so the search then runs with no ranking constraint at all rather than returning nothing. Include values are OR-joined (provider `anyOf`). The provider takes an include list only here, and the tiers nest, so an exclude value cannot be honoured and is ignored. This filter ANDs with the others.
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `officeLocationsV2` object[]: Office-location entries whose `value` is a country's three-letter `apiCode` from `countries` in GET /companies/filter-options (e.g. USA) — the same vocabulary as `headquartersCountryCode`, but matching ANY office rather than only the headquarters. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others.
      - `value` string, required: The filter value — see the field's own description for its vocabulary.
      - `label` string, required: Display label for the value (required; repeat the value when you have no label).
      - `status` 'include' | 'exclude', required: `include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies).
    - `linkedinSlugs` string[]: Free text: LinkedIn company slugs (e.g. stripe). A full company URL is accepted and reduced to the part after linkedin.com/company/, and the value is lower-cased, because the provider matches the slug exactly. Several slugs are OR-joined.
  - `savedSearchId` string: Id of one of your COMPANY saved searches to take the filters from instead of `filters` (a people saved search answers 422 SAVED_SEARCH_TYPE_MISMATCH).
  - `savedSearchName` string: Exact title of one of your company saved searches to take the filters from instead of `filters`; two searches sharing the title answer 409 SAVED_SEARCH_NAME_AMBIGUOUS.
  - `query` string: Natural-language description of the companies to find (max 2000 chars), converted into filters server-side instead of `filters`; criteria that could not be mapped come back as `unresolvedCriteria`, and a query yielding no filter answers 422 QUERY_FILTERS_INVALID.
  - `size` integer: Companies per page (1-100, default 25); the search pre-checks 2 credits per requested company and debits 2 credits per company returned.
  - `cursor` string, nullable: The `nextCursor` returned by the previous page, sent together with the same filter source; null (default) starts from the first page. The match `total` is only counted on the first page — it comes back null on every cursor page.

## Response `200`

Success

- object
  - `companies` object[], required
    - `isSaved` boolean, required: Whether this company is already in one of your company lists.
    - `preferred_name` string
    - `names` string[]
    - `domains` string[]
    - `linkedin_primary_slug` string, nullable
    - `standard_industries` string[]
    - `naics_codes` string[]
    - `tags` string[]
    - `status_consensus` string, nullable
    - `funding_stage` string, nullable
    - `employee_count_consensus` object, nullable
      - `gte` integer
      - `lte` integer
    - `location_consensus` object, nullable
  - `total` integer, nullable, required: True match count on the first page; null on every cursor page, where the upstream does not count.
  - `nextCursor` string, nullable, required: Send back as `cursor` with the same filter source for the next page; null on the last page.
  - `filters` object, required: The RESOLVED filters the search actually ran.
  - `unresolvedCriteria` string[]: Only when the source was `query`: criteria in the prose that could not be turned into a filter.

## Other responses

- `400`: Error
- `401`: Error
- `402`: Error
- `403`: Error
- `404`: Error
- `409`: Error
- `422`: Error
- `429`: Error
- `500`: Error

---

[API](https://skmtc.dev/fuseai/apis/fuse-business-api.md) · [All operations](https://skmtc.dev/fuseai/apis/fuse-business-api/llms.txt) · [OpenAPI document](https://skmtc.dev/fuseai/apis/fuse-business-api/revisions/50d95e0536f4?raw)
