# Company Search and Research API - B2B Firmographics (`nabeelbaghoor/company-search-research-api`) Actor

Search a B2B company database by industry, size, revenue, location, technology, news events and funding stage, then optionally run deep research for phones, full address and tech stack. Pay per result. Bring your own API key.

- **URL**: https://apify.com/nabeelbaghoor/company-search-research-api.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** Business, Developer tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$12.00 / 1,000 company results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Company Search and Research API - B2B Firmographics

Search a large B2B company database and export the matches as clean rows. Filter by industry, employee band, revenue band, country, state, postal code, keywords, company type, company age and the technologies a company runs, then narrow further by what just happened: an acquisition or expansion in the last 90 days, a Series B closed in the last year, a funding total inside a given band. Turn on deep research and each match is enriched further with phone numbers, the full address, the technology stack and a longer description. You pay only for the companies you actually receive.

This actor is built for building target account lists, timing outreach around news and funding events, and enriching an account list with the firmographics a CRM needs.

### What you can do with it

- Build an ideal customer profile list by industry, headcount band, revenue band and country.
- Find companies that raised a specific stage of funding inside a recency window.
- Target companies that just announced an acquisition, an expansion or another news event.
- Pull a list of every company in a market running a given technology.
- Enrich a list of domains you already have into full company records.
- Export everything as JSON, CSV or Excel, or push it into your CRM or warehouse.

### Features

- Every documented search filter is a real input field, with the provider's own per-field item limits enforced before the request goes out, so a search is never rejected for sending too many values.
- Filters that exceed a limit are trimmed and the trim is logged, never silently dropped.
- Optional deep research pass: matches are queued, polled until they settle, and merged onto the search rows.
- Research results are joined back by domain, then by company name, so a row is only enriched with data that genuinely belongs to it.
- Research is best effort. If it cannot be queued or does not finish in time, those rows keep their search data and the run continues.
- Cursor pagination is walked automatically, with a repeat-cursor guard so a stuck cursor cannot cause an endless loop.
- Comma-joined provider fields such as industries, phones and technologies are split back into clean arrays.
- Duplicate companies are removed across pages before anything is charged.
- Both the search payload and the research payload are kept under `raw`, so nothing is lost.
- Rate limits are handled with retry-after aware backoff, and a run that hits a limit keeps everything already collected.
- Pay-per-result pricing with a hard result cap so a run can never surprise you.

### Input

| Field | Type | Description |
| --- | --- | --- |
| `companyName` | array | Company names to match, up to 100. |
| `companyNameSearchType` | string | `default`, `related` or `exact`. |
| `companyDomain` | array | Company domains to match, up to 100. |
| `companyType` | string | `Public`, `Private`, or empty for both. |
| `companyCountry` / `companyState` / `companyZipCode` | array | Location filters, up to 10 each. |
| `industry` | array | Industries, up to 5. |
| `companyKeyword` | array | Description keywords, up to 10. |
| `companySize` / `companyRevenue` | array | Employee and revenue bands, up to 10 each. |
| `foundedOn` | array | Company age buckets, up to 4. |
| `technologies` | array | Technologies in use, up to 10. |
| `technologiesIsOr` | boolean | Match any technology instead of all. |
| `newsTypes` | array | News event types, up to 8. |
| `newsTypeDates` | array | News recency in days: 60, 90, 180 or 365. |
| `latestFundingDates` | array | Funding recency in days: 90, 180, 365 or 1095. |
| `latestFundingClassifications` | array | Funding stages, up to 14. |
| `latestFundingTotals` | array | Funding amount bands, up to 9. |
| `researchCompanies` | boolean | Run the deep research pass on every match. |
| `skipDeduplicationCheck` | boolean | Research again even if recently researched. |
| `rawFilters` | object | Any extra filter, merged last. |
| `maxResults` | integer | Stop after this many companies (1 to 20,000). |
| `pageSize` | integer | Companies per API call (1 to 100). |
| `apiKey` | string | Your API key. Required, stored securely. |

At least one filter is required.

### Example output

Each dataset item is one company. Fields are populated where the provider has data, and both payloads are kept under `raw`:

```json
{
  "searchResultId": "cmp_sr_01J8YQ4FXZQ6N5G2T3A7BC9D1E",
  "name": "Example Analytics",
  "domain": "example.com",
  "description": "Example Analytics builds revenue forecasting software for subscription businesses.",
  "industries": ["Computer Software", "Data Analytics"],
  "sicCode": "7372",
  "employeeCount": "310",
  "employeeRange": "201-500",
  "annualRevenue": "44000000",
  "revenueRange": "$25M-$50M",
  "foundedOn": "2013-04-01",
  "companyType": "Private",
  "stockTicker": null,
  "phones": ["+1 617-555-0188"],
  "street1": "88 Example Avenue",
  "city": "Boston",
  "state": "MA",
  "postCode": "02110",
  "country": "United States",
  "countryAlpha2": "US",
  "fullAddress": "88 Example Avenue, Boston, MA 02110, United States",
  "technologies": ["Snowflake", "dbt", "HubSpot"],
  "linkedin": "https://www.linkedin.com/company/example-analytics",
  "linkedInId": "10294857",
  "fundingTotal": "62000000",
  "latestFundingDate": "2025-09-16",
  "latestFundingClassifications": ["Series C"],
  "newsAndEvents": [
    {
      "title": "Example Analytics acquires Sample Metrics",
      "url": "https://news.example.com/acquisition",
      "date": "2026-06-02T00:00:00Z",
      "type": "Acquisition"
    }
  ],
  "numContacts": "412",
  "researched": true,
  "raw": { "search": { "name": "Example Analytics" }, "research": { "name": "Example Analytics" } }
}
```

### Pricing and the credit model

This actor uses pay-per-result pricing. You are charged a fixed price for each company delivered to the dataset, after duplicates are removed. A search that matches nothing costs nothing. Set `maxResults` to cap how many rows a run can collect, and set a run spending limit as a second safety net. Your own provider plan meters its own credits separately, and the research pass consumes more of them than search alone, so leave `researchCompanies` off for a broad discovery run and turn it on once the filters are right.

### Bring your own API key

This actor connects to a third-party B2B company data provider (Seamless.AI) on your behalf and requires your own provider API key. Create a key in the provider's platform and paste it into the `apiKey` input. It is stored securely and never logged, and the actor never ships with or shares credentials.

### Frequently asked questions

#### What data does this actor return?

Company name, domain and description, industries and SIC code, employee count and band, annual revenue and band, founded date, company type and stock ticker, phone numbers, the address broken into street, city, state, postal code and country, the technology stack, LinkedIn profile and id, total funding with the date and stage of the latest round, recent news and events with titles, links and dates, and the number of contacts the provider holds for the company. Every record also carries both untouched provider payloads.

#### What does deep research add over the search results?

Search returns the firmographic core straight away. The research pass adds phone numbers, the full structured address, the topmost technologies and a longer description. It runs asynchronously on the provider side, so the actor queues it, polls until each request settles, and merges what came back.

#### What happens if research does not finish?

Those rows keep their search data and the run carries on. Research is treated as an enhancement, never as a requirement, so a slow or failing research queue can never fail a search that already worked. The log reports how many requests did not settle in time.

#### How are research results matched back to search rows?

By website domain first, then by company name. The provider returns research keyed by its own request id, which does not map back to the search result that produced it, so a content match is the only safe join. A row that cannot be matched confidently is left with its search data rather than being enriched with someone else's record.

#### Why was one of my filters trimmed?

Each filter has a maximum number of values the API accepts, for example 5 industries and 10 technologies. Sending more is rejected outright by the provider, so the actor trims to the limit and logs exactly what it dropped. Split the extra values into a second run.

#### How do I search by recent news or funding?

Use `newsTypes` with `newsTypeDates` to require an event of a given type inside a recency window, and `latestFundingClassifications`, `latestFundingDates` and `latestFundingTotals` for funding. Both recency fields take exactly one value, which is a provider constraint rather than an actor one.

#### How does pagination work?

The API pages with an opaque cursor. The actor carries it forward automatically until it reaches `maxResults`, the provider signals there is no more, or the same cursor comes back twice, which is treated as the end rather than a loop.

#### How does the actor handle rate limits?

It throttles requests, honours the retry-after signal on a rate-limited response, and backs off exponentially. A response saying the account is out of credits stops the run early and keeps everything already collected.

#### How am I charged?

You pay a fixed price per company returned to the dataset. Duplicates are removed before charging and empty runs cost nothing. Use `maxResults` and the run spending limit to control cost.

#### What output formats are available?

The dataset can be exported as JSON, CSV, Excel, HTML or RSS, or read through the API for pushing into a CRM or warehouse.

### Keyword map

company search api, b2b company database api, firmographic data api, company enrichment api, find companies by technology, technographic search api, company funding data api, companies that raised funding, company news events api, acquisition signal data, employee band filter, revenue band filter, target account list builder, ideal customer profile search, account based marketing data, sic code company data, company phone number data, company address enrichment, b2b prospecting data, bulk company export.

# Actor input Schema

## `companyName` (type: `array`):

Company names to match, one per line. Up to 100.

## `companyNameSearchType` (type: `string`):

`default` is a normal name match, `exact` requires the whole name to match, and `related` also returns similar companies.

## `companyDomain` (type: `array`):

Company website domains to match, one per line, for example `example.com`. Up to 100.

## `companyType` (type: `string`):

Restrict to publicly traded or privately held companies. Leave unset to return both.

## `companyCountry` (type: `array`):

Countries to include, one per line, for example `US` or `Canada`. Up to 10.

## `companyState` (type: `array`):

States or provinces to include, one per line, for example `CA` or `TX`. Up to 10.

## `companyZipCode` (type: `array`):

Postal or ZIP codes to include, one per line. Up to 10.

## `industry` (type: `array`):

Industries to include, one per line, using the provider's own industry labels. Up to 5.

## `companyKeyword` (type: `array`):

Keywords to match against a company's description, one per line. Up to 10.

## `companySize` (type: `array`):

Employee count bands to include, one per line, using the provider's band labels. Up to 10.

## `companyRevenue` (type: `array`):

Annual revenue bands to include, one per line, using the provider's band labels. Up to 10.

## `foundedOn` (type: `array`):

Company age buckets to include, one per line, using the provider's own bucket labels. Up to 4.

## `technologies` (type: `array`):

Technologies the company runs, one per line. Up to 10.

## `technologiesIsOr` (type: `boolean`):

When enabled, a company matching any one of the listed technologies is returned. When off, a company must use all of them.

## `newsTypes` (type: `array`):

News and event types to require, one per line, for example `Acquisition` or `Expansion`. Up to 8.

## `newsTypeDates` (type: `array`):

How recent the news must be, as a single value: `60`, `90`, `180` or `365`. Only one value is accepted.

## `latestFundingDates` (type: `array`):

How recent the latest funding round must be, as a single value: `90`, `180`, `365` or `1095`. Only one value is accepted.

## `latestFundingClassifications` (type: `array`):

Funding stages to include, one per line, for example `Seed` or `Series B`. Up to 14.

## `latestFundingTotals` (type: `array`):

Total funding bands to include, one per line, using the provider's band labels. Up to 9.

## `researchCompanies` (type: `boolean`):

When enabled, every matched company is sent through the provider's research pass, which adds phone numbers, the full address, the technology stack and a longer description. Research is asynchronous and consumes extra provider credits. Rows whose research does not finish in time keep their search data.

## `skipDeduplicationCheck` (type: `boolean`):

When enabled, research runs again even for companies your account researched recently. Leave this off to reuse recent work and save provider credits.

## `rawFilters` (type: `object`):

Advanced. Any extra filter the data API supports, as a JSON object. Merged last, so it also overrides the fields above.

## `maxResults` (type: `integer`):

Stop after this many companies (1-20,000). One row is one company.

## `pageSize` (type: `integer`):

How many companies to fetch per API call (1-100). Larger pages mean fewer calls against your provider rate limit.

## `apiKey` (type: `string`):

Your own API key for the data provider. Required. It is created in the provider's platform. Stored securely here and never logged.

## Actor input object example

```json
{
  "companyName": [],
  "companyNameSearchType": "default",
  "companyDomain": [],
  "companyCountry": [],
  "companyState": [],
  "companyZipCode": [],
  "industry": [],
  "companyKeyword": [],
  "companySize": [],
  "companyRevenue": [],
  "foundedOn": [],
  "technologies": [],
  "technologiesIsOr": true,
  "newsTypes": [],
  "newsTypeDates": [],
  "latestFundingDates": [],
  "latestFundingClassifications": [],
  "latestFundingTotals": [],
  "researchCompanies": false,
  "skipDeduplicationCheck": false,
  "rawFilters": {},
  "maxResults": 100,
  "pageSize": 50
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "companyName": [],
    "companyDomain": [],
    "companyCountry": [],
    "companyState": [],
    "companyZipCode": [],
    "industry": [],
    "companyKeyword": [],
    "companySize": [],
    "companyRevenue": [],
    "foundedOn": [],
    "technologies": [],
    "newsTypes": [],
    "newsTypeDates": [],
    "latestFundingDates": [],
    "latestFundingClassifications": [],
    "latestFundingTotals": [],
    "rawFilters": {},
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/company-search-research-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "companyName": [],
    "companyDomain": [],
    "companyCountry": [],
    "companyState": [],
    "companyZipCode": [],
    "industry": [],
    "companyKeyword": [],
    "companySize": [],
    "companyRevenue": [],
    "foundedOn": [],
    "technologies": [],
    "newsTypes": [],
    "newsTypeDates": [],
    "latestFundingDates": [],
    "latestFundingClassifications": [],
    "latestFundingTotals": [],
    "rawFilters": {},
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/company-search-research-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "companyName": [],
  "companyDomain": [],
  "companyCountry": [],
  "companyState": [],
  "companyZipCode": [],
  "industry": [],
  "companyKeyword": [],
  "companySize": [],
  "companyRevenue": [],
  "foundedOn": [],
  "technologies": [],
  "newsTypes": [],
  "newsTypeDates": [],
  "latestFundingDates": [],
  "latestFundingClassifications": [],
  "latestFundingTotals": [],
  "rawFilters": {},
  "maxResults": 100
}' |
apify call nabeelbaghoor/company-search-research-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=nabeelbaghoor/company-search-research-api",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/4Sop2rhog9cuWfzXC/builds/DX2vwKCknDUOtNoiK/openapi.json
