# Brazil CNPJ Scraper: Company Search & Lookup (`enisbodlli/brazil-cnpj-company-search`) Actor

Look up Brazilian companies by CNPJ or search the Receita Federal register by state, city, CNAE code and legal form. Returns legal name, status, activities, address, phones and share capital. Company-level data: partners as a count, sole traders skipped. Filtered-out rows are never charged.

- **URL**: https://apify.com/enisbodlli/brazil-cnpj-company-search.md
- **Developed by:** [Enis Bodlli](https://apify.com/enisbodlli) (community)
- **Categories:** Lead generation, Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 company records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Brazil CNPJ Scraper: Company Search & Lookup

This **Brazil CNPJ scraper** looks up Brazilian companies by **CNPJ**, or **searches the Receita Federal's
company register** by state, city, CNAE activity code and legal form, and returns one clean row per
company: legal name, status, opening date, legal form, size, activities, address, phones and share
capital. It is built for teams that need **company records without people's data** for lead lists,
supplier checks, CRM enrichment and market sizing: partners are returned as a count, never as names, and
sole traders are skipped and counted. To try it, leave the two sample CNPJs in the input and click
**Start**: the run takes a few seconds.

- **Company-level rows only.** No partner names, roles or tax numbers. A sole trader, a MEI or another
  registration of a natural person is never returned; the run summary says how many were skipped.
- **You pay for the companies you get, not for the rows that were read.** A search row that fails the
  active, size or opening-date filter is neither stored nor charged. A looked-up CNPJ that is invalid,
  not in the register or registered to a person costs nothing.
- **No start fee of our own.** One event per company record and Apify's standard $0.00005 per run
  start. A run that looks up one CNPJ costs $0.00205.

A row looks like this (shortened; the full example is under [Output](#output)):

```json
{
    "cnpj": "33.000.167/0001-01",
    "legalName": "PETROLEO BRASILEIRO S A PETROBRAS",
    "status": "active",
    "openedOn": "1966-09-28",
    "legalNature": { "code": "2038", "text": "Sociedade de Economia Mista" },
    "companySize": "other",
    "mainActivity": { "code": "0600001", "text": "Extração de petróleo e gás natural" },
    "address": { "street": "AVENIDA REPUBLICA DO CHILE", "number": "65", "city": "RIO DE JANEIRO", "state": "RJ" },
    "phones": ["+552121660000"],
    "shareCapital": 205431960000,
    "partnersCount": 8
}
```

### How to look up a CNPJ or search Brazilian companies

1. **To look up companies**, paste their CNPJs under **CNPJs to look up**, one per line, with or without
   punctuation (`33.000.167/0001-01` or `33000167000101`). The alphanumeric CNPJ issued since July 2026
   (`12.ABC.345/01DE-35`) works too. Check digits are verified before anything is requested.
2. **To search**, fill at least one field under **Search the register**: states, a city (by name or by
   IBGE code), CNAE activity codes or legal forms. Then narrow the result with **Active companies only**,
   **Company sizes** or **Opened on or after**, and set **Maximum search results**.
3. You can do both in one run. Lookups run first; a company found by both is stored once.
4. Click **Start**. Rows are saved while the run works, so a run you stop keeps what it has.
5. Open the **Output** tab and export the table as JSON, CSV or Excel, or read it through the API.

### Pricing

You pay per **company record**: a dataset row with `"found": true`.

| Apify plan | Per 1,000 company records | Per record |
|---|---|---|
| Free, Bronze | $2.00 | $0.002 |
| Silver | $1.75 | $0.00175 |
| Gold | $1.50 | $0.0015 |

Plus Apify's standard $0.00005 per run start. Platform usage is included, so there is nothing else to pay.

- **A search for 1,000 active software companies in the state of São Paulo** (`states: ["SP"]`,
  `cnaeCodes: ["6201501"]`) read 2,251 register rows on 2026-10-07, dropped 873 companies that were not
  active and 378 sole traders, and stored 1,000 records: $2.00 on the Free and Bronze plans, $1.75 on
  Silver, $1.50 on Gold. The 1,251 rows that were read and dropped cost nothing.
- **A list of 200 CNPJs**, of which 180 are companies, 12 are sole traders, 5 are not in the register and
  3 have a typing mistake: 180 charges, $0.36 on the Free and Bronze plans. The other 20 cost nothing:
  17 get a row that says why, and the 3 mistyped ones are named in the run summary.

**What a run that stops early costs.** A record is charged at the moment its row is saved, and only then.
A run that fails, is aborted or is moved to another server has charged exactly the company records
(`"found": true`) in its dataset. When it is restarted or resurrected it continues where it was: a CNPJ
that already has a row is not fetched, stored or charged again. At most one search page is fetched a
second time.

You can set a maximum charge per run. The Actor then starts no lookup and fetches no page that the limit
could not pay for, stops when the limit is reached and says so in its status message.

### Input

| Field | What it does |
|---|---|
| CNPJs to look up (`cnpjs`) | CNPJs with or without punctuation, numeric or alphanumeric. Up to 5,000 per run. Repeats are looked up once. An entry whose check digits do not fit is skipped without a request. |
| States (`states`) | Two-letter state codes (UF). Runs at the source. |
| City (`city`) | One municipality by name (`São Paulo`, `campinas`) or 7-digit IBGE code (`3550308`). A name that exists in several states needs the state: `Bom Jesus, PI`. Runs at the source. |
| CNAE activity codes (`cnaeCodes`) | 7-digit CNAE subclass codes, `6201501` or `6201-5/01`. Matches the main activity. Runs at the source. |
| Also match secondary activities (`includeSecondaryCnae`) | Default off. When on, a company matches when the code is its main or one of its secondary activities. |
| Legal forms (`legalNatures`) | 4-digit legal-nature codes, for example `2062` (Sociedade Empresária Limitada) or `2054` (Sociedade Anônima Fechada). Runs at the source. Codes of natural persons are refused. |
| Active companies only (`activeOnly`) | Default on. Applied by the Actor to the rows it fetched. Search only. |
| Company sizes (`companySizes`) | `micro`, `small`, `other`. Empty keeps every size. Applied by the Actor. Search only. |
| Opened on or after (`openedAfter`) | A date, `YYYY-MM-DD`. Applied by the Actor. Search only; use it with a narrow search. |
| Maximum search results (`maxResults`) | Default 100, at most 100,000. The search stops when this many companies are stored. Lookups are not counted. |

A search needs at least one of `states`, `city`, `cnaeCodes` or `legalNatures`: those are the only filters
the register source has. Input that cannot be used (an unknown state, an ambiguous city, a CNAE code with
fewer than 7 digits, nothing to do) fails the run before any request, with one sentence that says what to
enter instead.

Look up three companies:

```json
{
    "cnpjs": ["33.000.167/0001-01", "00.000.000/0001-91", "60.746.948/0001-12"]
}
```

Active small and larger software companies in Campinas, opened since 2024:

```json
{
    "city": "Campinas",
    "cnaeCodes": ["6201501", "6202300"],
    "activeOnly": true,
    "companySizes": ["small", "other"],
    "openedAfter": "2024-01-01",
    "maxResults": 200
}
```

Limited companies and corporations in two states:

```json
{
    "states": ["SC", "PR"],
    "legalNatures": ["2062", "2054"],
    "cnaeCodes": ["4711302"],
    "includeSecondaryCnae": true,
    "maxResults": 5000
}
```

### Output

One row per CNPJ. `cnpjDigits` is unique within a run. A head office and each of its branches have their
own CNPJ and their own row (`isHeadOffice` tells them apart). Every field is always present; `null` means
the register does not say. Lookups come out in the order of the input, search results in the order the
source returns them (not by name or date).

```json
[
    {
        "cnpj": "33.000.167/0001-01",
        "cnpjDigits": "33000167000101",
        "found": true,
        "outcome": "found",
        "note": null,
        "legalName": "PETROLEO BRASILEIRO S A PETROBRAS",
        "tradeName": "PETROBRAS - EDISE",
        "status": "active",
        "statusRaw": "ATIVA",
        "statusDate": "2005-11-03",
        "statusReason": null,
        "specialStatus": null,
        "openedOn": "1966-09-28",
        "legalNature": { "code": "2038", "text": "Sociedade de Economia Mista" },
        "companySize": "other",
        "shareCapital": 205431960000,
        "mainActivity": { "code": "0600001", "text": "Extração de petróleo e gás natural" },
        "secondaryActivities": [
            { "code": "1921700", "text": "Fabricação de produtos do refino de petróleo" },
            { "code": "3520401", "text": "Produção de gás; processamento de gás natural" }
        ],
        "address": {
            "street": "AVENIDA REPUBLICA DO CHILE",
            "number": "65",
            "complement": null,
            "district": "CENTRO",
            "city": "RIO DE JANEIRO",
            "cityCode": "3304557",
            "state": "RJ",
            "postalCode": "20031170"
        },
        "phones": ["+552121660000"],
        "email": null,
        "isHeadOffice": true,
        "simplesOptant": null,
        "taxRegimes": [
            { "year": 2023, "regime": "LUCRO REAL" },
            { "year": 2024, "regime": "LUCRO REAL" }
        ],
        "partnersCount": 8,
        "registryDataDate": "2026-09",
        "source": "minhareceita.org",
        "sourceUrl": "https://minhareceita.org/33000167000101",
        "scrapedAt": "2026-10-07T21:36:12.420Z"
    },
    {
        "cnpj": "00.000.000/0001-91",
        "cnpjDigits": "00000000000191",
        "found": true,
        "outcome": "found",
        "note": null,
        "legalName": "BANCO DO BRASIL SA",
        "tradeName": "DIRECAO GERAL",
        "status": "active",
        "statusRaw": "ATIVA",
        "statusDate": "2005-11-03",
        "statusReason": null,
        "specialStatus": null,
        "openedOn": "1966-08-01",
        "legalNature": { "code": "2038", "text": "Sociedade de Economia Mista" },
        "companySize": "other",
        "shareCapital": 120000000000,
        "mainActivity": { "code": "6422100", "text": "Bancos múltiplos, com carteira comercial" },
        "secondaryActivities": [
            { "code": "6499999", "text": "Outras atividades de serviços financeiros não especificadas anteriormente" }
        ],
        "address": {
            "street": "QUADRA SAUN QUADRA 5 BLOCO B TORRE I, II, III",
            "number": "SN",
            "complement": "ANDAR T I SL S101 A S1602 T II SL C101 A C1602 TIII SL N101 A N1602",
            "district": "ASA NORTE",
            "city": "BRASILIA",
            "cityCode": "5300108",
            "state": "DF",
            "postalCode": "70040912"
        },
        "phones": ["+556134939002"],
        "email": null,
        "isHeadOffice": true,
        "simplesOptant": false,
        "taxRegimes": [
            { "year": 2023, "regime": "LUCRO REAL" },
            { "year": 2024, "regime": "LUCRO REAL" }
        ],
        "partnersCount": 41,
        "registryDataDate": "2026-09",
        "source": "minhareceita.org",
        "sourceUrl": "https://minhareceita.org/00000000000191",
        "scrapedAt": "2026-10-07T21:36:12.745Z"
    },
    {
        "cnpj": "12.ABC.345/01DE-35",
        "cnpjDigits": "12ABC34501DE35",
        "found": false,
        "outcome": "not_found",
        "note": "The register has no company with this CNPJ.",
        "legalName": null,
        "tradeName": null,
        "status": null,
        "statusRaw": null,
        "statusDate": null,
        "statusReason": null,
        "specialStatus": null,
        "openedOn": null,
        "legalNature": null,
        "companySize": null,
        "shareCapital": null,
        "mainActivity": null,
        "secondaryActivities": [],
        "address": {
            "street": null,
            "number": null,
            "complement": null,
            "district": null,
            "city": null,
            "cityCode": null,
            "state": null,
            "postalCode": null
        },
        "phones": [],
        "email": null,
        "isHeadOffice": null,
        "simplesOptant": null,
        "taxRegimes": [],
        "partnersCount": null,
        "registryDataDate": "2026-09",
        "source": "minhareceita.org",
        "sourceUrl": null,
        "scrapedAt": "2026-10-07T21:37:02.118Z"
    }
]
```

The first two rows are the output of the sample input on 2026-10-07, with the lists of secondary
activities and tax regimes shortened. The third is what a valid CNPJ that is not in the register gives: a
row that says so, and no charge.

#### What `outcome` means

| `outcome` | `found` | Charged | Meaning |
|---|---|---|---|
| `found` | `true` | yes | A company record. Every search result is one. |
| `not_found` | `false` | no | The register has no such CNPJ. |
| `natural_person_skipped` | `false` | no | The CNPJ belongs to a sole trader, a MEI or another registration of a person. The row carries the number and the reason, nothing else. |

#### The run summary

The key-value store record `RUN_SUMMARY` holds the same facts for programs: `recordsStored` and
`chargedEvents`, `scanned`, `filteredOut`, `soleTradersSkipped`, `scanCapReached`, the reason the run
stopped (`stopReason`), and for lookups the invalid entries and the CNPJs that could not be looked up,
each with its reason.

### Where each filter runs

The register source can filter by state, municipality, CNAE code and legal form, and by nothing else. So:

| Filter | Runs | What that means |
|---|---|---|
| `states`, `city`, `cnaeCodes`, `legalNatures` | at the source | Only matching rows are read. |
| `activeOnly`, `companySizes`, `openedAfter` | in the Actor | Matching rows are read page by page, and the ones that fail are dropped. Dropped rows are not charged. |

About half of the register is closed, suspended or unfit companies and close to a fifth is sole traders:
of 1,000 rows sampled on 2026-10-07, 421 were active companies. With `activeOnly` on, the Actor reads
between 2 and 2.5 rows for every record it stores.

### Limits

- **People's data is left out, on purpose.** The register's partner list (names, roles, masked CPFs, entry
  dates, age bands) is not returned; `partnersCount` is the only thing taken from it. If you need partner
  names for KYC or to address a person, this Actor is the wrong tool.
- **No search by a partner's CPF.** That is a search for a person.
- **Sole traders, MEI and other registrations of natural persons are never returned** (legal nature 2135,
  the 4000 to 4999 block, any MEI, and any legal name that carries a CPF). Their legal name is a person's
  name. The same holds for two registrations that are no legal entity: consortia of rural employers
  (2283, registered as "a person's name and others") and notary offices (3034, a public office delegated
  to a person). All of them are skipped and counted in `soleTradersSkipped`. A company named after its
  owner, or a company phone that is somebody's mobile, can still point at a person: that is how the
  register is.
- **What the register says about an owner is left out.** `statusReason` and `specialStatus` are `null`
  when the register's text describes a person and not the company: the estate or death of an owner, or
  an owner who is incapacitated or under interdiction.
- **No search by company name.** The source has none.
- **`email` is `null` in practice.** The current register extract carries no email addresses (0 of 1,000
  sampled rows on 2026-10-07). The field is there for the day it does.
- **Status, size and opening date are not filtered at the source.** They run in the Actor, as described
  above. `openedAfter` is only practical on a narrow search (one city or one CNAE code): the source does
  not sort by date, so on a broad search most rows are read and dropped.
- **The scan cap.** A search may read 20,000 rows plus 200 for every company it has stored, and at most
  300,000 rows in one run. A search whose filters keep fewer than about 1 row in 200 therefore ends early,
  with `scanCapReached: true` and whatever it found. Narrow it with a state, a city or a CNAE code.
- **Not real time.** The source follows the Receita Federal's monthly extract. `registryDataDate` on every
  row says which month (`2026-09` when this was written). A company opened or closed after that is not
  reflected yet.
- **One database, no service level.** Records come from `minhareceita.org`, a volunteer-run mirror of the
  register, asked one request at a time with a pause. When it does not answer a lookup (timeouts, server
  errors or "too many requests" that outlast the retries), the lookup is tried through `brasilapi.com.br`,
  which serves the same data, at one request a second and for at most 200 CNPJs a run; `source` says
  which path answered. The second path is never used after "not found" or after a refusal, and never for
  search.
- **No lookups through `publica.cnpj.ws`.** Its terms forbid passing on the data of its API commercially.
- **No lookups through `open.cnpja.com`.** Its terms could not be read with a plain request, so it is
  not used.
- **A refusal is final.** If the source answers 403 or shows a bot check, the run stops and says so. The
  Actor uses no proxy and no browser and does not try to get around a refusal. When the source is down,
  the run keeps what it stored and can be resurrected to continue. It is marked failed whenever a refusal
  or an outage stopped it before the work was done, whatever it stored first, and when more of its
  CNPJs went without an answer than were answered.
- **A code that does not exist gets no answer.** The source answers a search for a real CNAE or
  legal-nature code in well under a second, and does not answer at all when the code does not exist and
  no state or city narrows the search (measured 2026-10-08). The run then waits for its deadline, fails
  and says to check the codes. A code made of zeros is refused before any request.
- **Paged search is marked "in test phase" by the source.** Its format may change. The Actor checks every
  page before reading it and fails with a clear message rather than returning wrong rows.
- **Fields that are not returned:** the partner graph, any risk score, derived company age, fax, the
  dates of entering or leaving Simples and MEI, foreign-address fields and the public-body field.
- **Sizes and speed.** 5,000 CNPJs and 100,000 search results per run. Lookups are sent one at a time
  with a quarter-second pause, about 150 a minute when the source answers as fast as it did on
  2026-10-07 (0.15 s). A search reads about 1,000 rows every 6 seconds.

### FAQ

#### Is it legal to scrape Brazilian company data?

The CNPJ register is public: the Receita Federal publishes it as open data every month. This Actor reads
that data through open, keyless endpoints
without logging in, and leaves out the parts that describe people. One of the two hosts,
`brasilapi.com.br`, asks in its terms not to be used by automated tools; the Actor uses it only as the slow
fallback described above. You are responsible for how you use the data, including Brazil's data protection
law (LGPD) when a record can be linked to a person. This is not legal advice.

#### Why is a CNPJ "not found" when the company exists?

The data is a monthly extract. A company registered after the month in `registryDataDate` is not in it
yet. Also check the number: the Actor only looks up CNPJs whose check digits are right.

#### Why did my search return fewer companies than `maxResults`?

Either the register has no more rows for that search (`search.reachedLastPage` in the run summary), or the
filters dropped most rows and the scan cap ended the run (`scanCapReached`). `filteredOut` and
`soleTradersSkipped` show how many rows were read and dropped.

#### Why is there no row for one of my CNPJs?

Entries that are not a valid CNPJ get no row and no request; they are listed in `RUN_SUMMARY` under
`lookup.invalid` with the reason. A CNPJ that no source could answer is listed under `lookup.failed` and
has no row either, so that a later run can try it again.

#### Can I get the partners or the owner of a company?

No. See Limits: the Actor returns how many partners the register lists and nothing about who they are.

#### Can I search by city name?

Yes. Accents and capitals do not matter. If the name exists in more than one state, the run stops before
doing anything and lists the candidates; add the state (`Bom Jesus, PI`) or use the IBGE code.

#### How long does a run take?

One lookup takes under half a second, pause included, so 1,000 CNPJs take about 7 minutes. The search for
1,000 active companies in the pricing example took about 20 seconds on 2026-10-07. Both depend on how
fast the source answers.

#### Where do I report a problem?

On the **Issues** tab of this Actor. Include the run ID.

### More Actors from this developer

Company registers:

- [North Data Scraper: German & European Companies](https://apify.com/enisbodlli/northdata-company-scraper)
- [Handelsregister Scraper: German Company Register](https://apify.com/enisbodlli/handelsregister-scraper)
- [US Business Entity Search & New Business Filings](https://apify.com/enisbodlli/us-business-registry-search)
- [European Company Registry Search](https://apify.com/enisbodlli/eu-company-registry-search)

Contacts and lists:

- [Website Contact Scraper](https://apify.com/enisbodlli/website-contact-scraper)
- [Email Validator & List Cleaner](https://apify.com/enisbodlli/email-validator)

Jobs:

- [Company Jobs Search](https://apify.com/enisbodlli/company-jobs-search)
- [ATS Job Postings: Workday, Greenhouse, Lever & Ashby](https://apify.com/enisbodlli/ats-job-postings)
- [Workday Jobs Scraper](https://apify.com/enisbodlli/workday-jobs-scraper)
- [Greenhouse Jobs Scraper](https://apify.com/enisbodlli/greenhouse-jobs-scraper)
- [Lever Jobs Scraper](https://apify.com/enisbodlli/lever-jobs-scraper)
- [Ashby Jobs Scraper](https://apify.com/enisbodlli/ashby-jobs-scraper)

# Changelog

This Actor's version history is a separate document: https://apify.com/enisbodlli/brazil-cnpj-company-search/changelog.md

# Actor input Schema

## `cnpjs` (type: `array`):

CNPJ numbers, one per line, with or without punctuation (33.000.167/0001-01 or 33000167000101). The new alphanumeric CNPJ (12.ABC.345/01DE-35) is accepted too. Check digits are verified before any request: an entry that fails is skipped, named in the run summary and costs nothing. Repeated numbers are looked up once. Every valid CNPJ gives one row; only rows with a company are charged. Up to 5,000 per run.

## `states` (type: `array`):

Search companies registered in these Brazilian states. Applied by the register source. A search needs at least one of: states, city, CNAE codes, legal forms.

## `city` (type: `string`):

One municipality, by name (São Paulo, Campinas) or by its 7-digit IBGE code (3550308). Accents and capitals do not matter. A name that exists in several states, such as Bom Jesus, needs the state: write "Bom Jesus, PI" or select the state above. An unknown or ambiguous name stops the run before any work, with the possible matches in the message.

## `cnaeCodes` (type: `array`):

CNAE subclass codes, all 7 digits, with or without punctuation: 6201501 or 6201-5/01 (custom software development). A company matches when its main activity is one of the codes. Applied by the register source. Check the code: the source does not answer a search for a code that does not exist.

## `includeSecondaryCnae` (type: `boolean`):

When on, a company matches the CNAE codes above if its main activity or any of its secondary activities is one of them. When off, only the main activity counts.

## `legalNatures` (type: `array`):

4-digit legal-nature codes, with or without the hyphen: 2062 (Sociedade Empresária Limitada), 2054 (Sociedade Anônima Fechada), 2046 (Sociedade Anônima Aberta), 2240 (Sociedade Simples Limitada), 3069 (Fundação Privada). Applied by the register source. Codes of natural persons are refused, because this Actor returns companies only: 2135 (sole trader), 4000 to 4999, 2283 (consortium of rural employers) and 3034 (notary office). Check the code: the source does not answer a search for a code that does not exist.

## `activeOnly` (type: `boolean`):

Keep only companies whose registration status is active (ATIVA). About half the register is closed, suspended or unfit companies. The register source cannot filter by status, so the Actor filters the rows it fetched: a row that is dropped is not stored and not charged. Applies to search only; a looked-up CNPJ is returned whatever its status.

## `companySizes` (type: `array`):

Keep only companies of these sizes (the register's "porte"). Empty keeps every size. Filtered by the Actor after fetching; dropped rows are not charged. Applies to search only.

## `openedAfter` (type: `string`):

Keep only companies that started activity on or after this date (YYYY-MM-DD). Filtered by the Actor after fetching; dropped rows are not charged. The source does not sort by date and its data is a monthly extract, so use this with a narrow search (one city or one CNAE code): on a broad search most rows are read and dropped, and the scan cap ends the run early.

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

The search stops when this many companies are stored. It limits what a search can cost: each stored company is one charged event. Lookups are not counted: every CNPJ in the list above is looked up.

## Actor input object example

```json
{
  "cnpjs": [
    "33.000.167/0001-01",
    "00.000.000/0001-91"
  ],
  "states": [
    "SP",
    "RJ"
  ],
  "city": "Campinas",
  "cnaeCodes": [
    "6201501",
    "6202300"
  ],
  "includeSecondaryCnae": false,
  "legalNatures": [
    "2062",
    "2054"
  ],
  "activeOnly": true,
  "companySizes": [
    "small",
    "other"
  ],
  "openedAfter": "2025-01-01",
  "maxResults": 100
}
```

# Actor output Schema

## `results` (type: `string`):

One row per CNPJ, in the run's default dataset: legal name, status, legal form, size, activities, address, phones, share capital and the number of partners. Rows with "found": true are company records and the only ones charged.

## `runSummary` (type: `string`):

Totals for the run: records stored and charged, rows read, rows filtered out, sole traders skipped, invalid and failed lookups with the reason, and why the run stopped.

# 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 = {
    "cnpjs": [
        "33.000.167/0001-01",
        "00.000.000/0001-91"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("enisbodlli/brazil-cnpj-company-search").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 = { "cnpjs": [
        "33.000.167/0001-01",
        "00.000.000/0001-91",
    ] }

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

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

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

```

## CLI example

```bash
echo '{
  "cnpjs": [
    "33.000.167/0001-01",
    "00.000.000/0001-91"
  ]
}' |
apify call enisbodlli/brazil-cnpj-company-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,enisbodlli/brazil-cnpj-company-search"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/PIJ12sxQT1rRb8HWO/builds/uw6CjgPEkJxUxBG86/openapi.json
