# OpenCorporates Scraper (`memo23/opencorporates-scraper`) Actor

Scrape OpenCorporates company records from 140+ jurisdictions by country or state code, or by company URL. Get status, type, address, industry codes, EIN/CIK, previous names, filings and officer counts. Add your own OpenCorporates login for directors, owners and incorporation dates.

- **URL**: https://apify.com/memo23/opencorporates-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Lead generation, AI
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 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.

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

## OpenCorporates Scraper

Get company registry records from OpenCorporates for any of 140+ jurisdictions, as clean rows you can open in Excel or feed to an API.
Pick a jurisdiction code (gb, fr, nl, us_ca, ca_on, …) or paste company URLs, and get the name, company number, status, type, registered address, industry codes, identifiers such as EIN and SEC CIK, previous names, filings and officer counts. Turn on officer enrichment (`includeOfficers`, off by default, no account needed on your side) and each row also carries directors and officers with their dates, beneficial owners, incorporation and dissolution dates, and the official registry source.

### Why Use This Scraper?

- ✅ Bulk company lists by jurisdiction: 140+ countries, US states and Canadian provinces
- ✅ Targeted lookups by company URL, mixed freely with jurisdictions
- ✅ Every field shown on the company page, already structured: ISO dates, split address lines, typed identifiers
- ✅ Industry codes (UK SIC, NACE, ISIC, NAF), EIN, SEC CIK, CAGE and previous company numbers where the registry has them
- ✅ Optional officer enrichment: directors/officers, beneficial owners and incorporation dates, with no OpenCorporates account of your own
- ✅ Pay per company record. Removed or empty company pages are skipped and never billed
- ✅ No API key needed

### Overview

The OpenCorporates Scraper is for compliance and KYB teams, sales and lead-generation teams, researchers and data buyers who need company registry data from many countries in one consistent format.

Each dataset row is one company. Fields that a registry does not publish come back as `null` (or an empty list), so every row has the same shape and exports cleanly to CSV.

Discovery works two ways: by jurisdiction, where the actor lists companies registered there (active and dissolved), or by the company URLs you paste. Keyword or name search is not offered.

### Supported Inputs

#### Jurisdiction codes

| Format | Pattern | Examples |
|---|---|---|
| Country | `{country}` | `gb`, `fr`, `de`, `nl`, `ie`, `es`, `fi`, `no`, `dk`, `jp`, `au`, `nz`, `br`, `in`, `sg`, `hk` |
| State or province | `{country}_{state}` | `us_ca`, `us_ny`, `us_tx`, `us_fl`, `us_de`, `ca_on`, `ca_bc`, `ca_qc` |
| All states of a country | `{country}` | `us` (every US state), `ca` (federal + every province) |

An unknown code stops the run right away, with the list of valid country codes in the message.

#### Company URLs

```json
{
  "startUrls": [
    "https://opencorporates.com/companies/gb/05957738",
    "https://opencorporates.com/companies/us_ca/C0806592",
    "https://opencorporates.com/companies/nl/17087985"
  ]
}
```

URLs without `https://`, with a trailing slash or with query parameters are accepted. Anything that is not a company page is skipped and named in the log.

#### Unsupported inputs

- ❌ Name or keyword search (`?q=apple`)
- ❌ Officer pages (`/officers/...`), filings pages, network graphs
- ❌ Company lists filtered by status, industry or date. Filter the dataset after the run instead

### Use Cases

| Audience | Use case |
|---|---|
| **Compliance / KYB teams** | Verify registration status, registered address and officers of counterparties |
| **Sales & lead generation** | Build lists of registered businesses by country, state and industry code |
| **Market researchers** | Size company populations by jurisdiction, type and industry |
| **Due diligence & investigations** | Pull officer histories, beneficial owners and previous names |
| **Data teams** | Enrich CRM records with company numbers, EIN / CIK and registry links |
| **Academics** | Study company formation and dissolution across jurisdictions |

### How It Works

![How It Works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-opencorporates.png)

1. **Input**: jurisdiction codes, company URLs, or both
2. **Find**: the actor lists companies registered in your jurisdictions
3. **Read**: each company page is loaded and every field is read into a structured row
4. **Optional enrichment**: with officer enrichment on, officers, owners and dates are added
5. **Output**: one row per company, as JSON, CSV, Excel or through the API

### Input Configuration

#### Input fields

| Field | Type | Required | Notes |
|---|---|---|---|
| `jurisdictions` | `array<string>` | one of the two | Jurisdiction codes, e.g. `gb`, `fr`, `us_ca` |
| `startUrls` | `array<string>` | one of the two | `opencorporates.com/companies/{jurisdiction}/{number}` URLs |
| `includeOfficers` | `boolean` | optional | Director/officer enrichment, charged additionally per enriched record. Default `false` |
| `maxItems` | `integer` | optional | Stop after this many companies. Default `1000` |
| `maxConcurrency` | `integer` | optional | Company pages loaded in parallel. Default `15`, max `20` |
| `startOffset` | `integer` | optional | Skip this many companies of the jurisdictions, to continue after an earlier run. Default `0` |
| `recordMaxAgeDays` | `integer` | optional | Return companies collected in the last N days at once instead of loading them again. Default `30`, `0` = always fresh |
| `proxy` | `object` | optional | Residential proxies recommended. The default works out of the box |

#### Common scenarios

**1. All companies in a jurisdiction, capped**

```json
{
  "jurisdictions": ["gb"],
  "maxItems": 5000
}
```

**2. Specific companies by URL**

```json
{
  "startUrls": [
    "https://opencorporates.com/companies/gb/05957738",
    "https://opencorporates.com/companies/us_ca/C0806592"
  ]
}
```

**3. With officers, owners and incorporation dates**

```json
{
  "jurisdictions": ["us_ny"],
  "includeOfficers": true,
  "maxItems": 1000
}
```

### Output Overview

Each row is one company:

- **Core**: name, company number, status, company type, jurisdiction and its code
- **Address**: the registered address as one string and as separate lines
- **Classification**: industry codes in every scheme the registry publishes
- **Identifiers**: EIN, SEC CIK, CAGE, previous company numbers and previous names
- **Agent**: registered agent name and address (mostly US states)
- **Activity**: latest accounts date, annual return date, recent filings with links
- **People**: number of active and inactive officers and beneficial owners; with officer enrichment on, the names, roles and dates
- **Source** (with officer enrichment): the official registry, its link and how fresh the data is
- **Meta**: `loginRequiredFields` lists what OpenCorporates kept for signed-in users on that page, plus `url` and `scrapedAt`

Coverage depends on the registry: GB rows usually carry industry codes and accounts dates, US rows carry agents and filings, French rows carry NAF codes and employee bands, and some registries (Spain, for example) publish little more than name, number and type.

### Output Samples

#### UK company, public fields

```json
{
  "name": "LIBRA INVESTMENT PROPERTY GROUP LIMITED",
  "companyNumber": "05957738",
  "status": "Active",
  "incorporationDate": null,
  "dissolutionDate": null,
  "companyType": "Private Limited Company",
  "jurisdiction": "United Kingdom",
  "jurisdictionCode": "gb",
  "registeredAddress": "Penycastell Farm, Bryn, Port Talbot, SA13 2PY, West Glamorgan, United Kingdom",
  "registeredAddressLines": ["Penycastell Farm, Bryn", "Port Talbot", "SA13 2PY", "West Glamorgan", "United Kingdom"],
  "agentName": null,
  "agentAddress": null,
  "industryCodes": [
    "70.10: Activities of head offices (UK SIC Classification 2007)",
    "70.10: Activities of head offices (European Community NACE Rev 2)",
    "7010: Activities of head offices (UN ISIC Rev 4)"
  ],
  "previousNames": ["£IBRA FINANCIAL SERVICES LIMITED"],
  "previousCompanyNumbers": [],
  "otherIdentifiers": [],
  "latestAccountsDate": "2025-03-31",
  "annualReturnLastMadeUpDate": "2015-10-05",
  "registryPage": null,
  "officersCount": 2,
  "inactiveOfficersCount": 3,
  "beneficialOwnersCount": 3,
  "beneficialOwners": [],
  "directorsOfficers": [],
  "recentFilings": [],
  "dataSource": null,
  "otherAttributes": {},
  "loginRequiredFields": ["incorporationDate", "ultimateBeneficialOwners", "directorsOfficers", "inactiveDirectorsOfficers", "dataSource"],
  "url": "https://opencorporates.com/companies/gb/05957738",
  "scrapedAt": "2026-10-30T06:55:52.802Z"
}
```

#### Same company, with officer enrichment (lists shortened)

```json
{
  "name": "LIBRA INVESTMENT PROPERTY GROUP LIMITED",
  "companyNumber": "05957738",
  "status": "Active",
  "incorporationDate": "2006-10-05",
  "jurisdictionCode": "gb",
  "registryPage": "https://beta.companieshouse.gov.uk/company/05957738",
  "officersCount": 2,
  "inactiveOfficersCount": 3,
  "beneficialOwnersCount": 3,
  "beneficialOwners": ["Mr David Ian Bromley", "Mr David Ian Bromley-Cornfield", "Mrs Elizabeth Davies"],
  "directorsOfficers": [
    { "name": "DAVID IAN BROMLEY-CORNFIELD", "position": "director", "startDate": "1 Oct 2010", "endDate": null, "isActive": true, "isCorporate": false, "link": "https://opencorporates.com/officers/201499282" },
    { "name": "PHOENIX AUDIT LIMITED", "position": "secretary", "startDate": "5 Oct 2006", "endDate": "5 Oct 2009", "isActive": false, "isCorporate": true, "link": "https://opencorporates.com/officers/201499267" }
  ],
  "dataSource": {
    "name": "UK Companies House",
    "url": "https://beta.companieshouse.gov.uk/company/05957738",
    "lastUpdateFromSource": "29 October 2026",
    "lastChangeRecorded": "28 September 2026",
    "nextUpdateFromSource": "Daily"
  },
  "loginRequiredFields": []
}
```

#### California company, public fields (identifiers and filings)

```json
{
  "name": "APPLE INC.",
  "companyNumber": "0806592",
  "status": "Active",
  "companyType": "Stock Corporation - CA - General",
  "jurisdiction": "California (US)",
  "jurisdictionCode": "us_ca",
  "registeredAddress": "ONE APPLE PARK WAY, CUPERTINO, 95014, CA, United States",
  "agentName": "C T CORPORATION SYSTEM",
  "agentAddress": "330 N BRAND BLVD STE # 700, GLENDALE, CA, 91203, UNITED STATES",
  "previousCompanyNumbers": ["C0806592"],
  "otherIdentifiers": [
    { "type": "US Federal CAGE number", "value": "58839" },
    { "type": "SEC CIK number", "value": "320193" },
    { "type": "US EIN number", "value": "942404110" }
  ],
  "officersCount": 25,
  "inactiveOfficersCount": 29,
  "recentFilings": [
    { "date": "28 Jan 2022", "title": "PUBLICLY TRADED DISCLOSURE", "url": "https://opencorporates.com/filings/1070407905" }
  ]
}
```

### Key Output Fields

#### Company core

- `name`, `companyNumber`, `status`, `companyType`, `jurisdiction`, `jurisdictionCode`
- `incorporationDate`, `dissolutionDate`: ISO `YYYY-MM-DD` (officer enrichment)

#### Address and agent

- `registeredAddress` (one string), `registeredAddressLines` (array)
- `agentName`, `agentAddress`

#### Classification and identifiers

- `industryCodes`: e.g. `"70.10: Activities of head offices (UK SIC Classification 2007)"`
- `otherIdentifiers[]`: `{type, value}`, e.g. EIN, SEC CIK, CAGE
- `previousNames`, `previousCompanyNumbers`

#### Activity

- `latestAccountsDate`, `annualReturnLastMadeUpDate`
- `recentFilings[]`: `{date, title, url}`

#### People

- `officersCount`, `inactiveOfficersCount`, `beneficialOwnersCount`
- `directorsOfficers[]` (officer enrichment): `{name, position, startDate, endDate, isActive, isCorporate, link}`
- `beneficialOwners[]` (officer enrichment)

#### Source and meta

- `dataSource` (officer enrichment): `{name, url, lastUpdateFromSource, lastChangeRecorded, nextUpdateFromSource}`
- `registryPage`: link to the company in the official registry (officer enrichment)
- `otherAttributes`: any extra registry field, e.g. `numberOfEmployees`, `alternativeNames`, `branch`
- `loginRequiredFields`: fields held back for signed-in users on that page
- `url`, `scrapedAt`

### FAQ

#### Which jurisdictions are supported?

140+, including most European countries, Japan, Australia, New Zealand, Brazil, India, Singapore, Hong Kong, every US state and the Canadian provinces. Use the two-letter country code, or `country_state` for US states and Canadian provinces. `us` alone covers all US states.

#### Do I need an OpenCorporates account?

No. Every field this actor offers is available without an account of your own. The base record covers what OpenCorporates shows to visitors: name, number, status, type, address, industry codes, identifiers, previous names, filings and officer counts. Officer enrichment (`includeOfficers: true`, off by default) adds officer names and dates, beneficial owners, incorporation and dissolution dates, and the registry source — the actor signs in with its own account pool, so you never supply credentials.

#### What does officer enrichment cost?

One extra event per enriched company record, on top of the base record price. It is off by default; turn `includeOfficers` on when you need officers, owners or incorporation dates. Enrichment is charged only on rows that actually carry it: if it is unavailable, or runs out partway through a very large run, the remaining rows come with the public fields and no enrichment charge.

#### Can I search by company name?

No. Find companies by jurisdiction, or paste the company URLs you already have.

#### Can I mix jurisdictions and URLs?

Yes. Both run together and each company appears once, matched on jurisdiction and company number.

#### How many results can I get, and how fast?

A jurisdiction can return tens of thousands of companies, so set `maxItems`. In our test runs the default settings loaded about 750 companies a minute. Companies already collected in the last 30 days are returned almost at once: a repeat run of 300 companies finished in seconds.

#### Can I get the next batch of companies after a run?

Yes. Run again with `startOffset` set to the number of companies you already have, for example `"startOffset": 1000` after a run of 1,000. The order can change when OpenCorporates updates its listings, so continue soon after the earlier run; a few companies may repeat or be missed if a lot of time has passed.

#### How fresh is the data?

Companies loaded for any run in the last 30 days are reused instead of being loaded again, which makes repeat lookups much faster. Each row's `scrapedAt` shows when it was collected. Set `recordMaxAgeDays` lower for fresher data, or to `0` to load every company fresh.

#### What am I billed for?

One event per company row in the dataset, plus one officer-enrichment event for each row that was actually enriched. Pages that no longer exist or hold no company record are skipped and not billed, and `maxItems` is never exceeded. Free-plan users get up to 100 companies per run.

#### Why are some fields `null`?

Either the registry does not publish them, or OpenCorporates shows them only to signed-in users. In the second case the field name appears in `loginRequiredFields`.

### Support

Found a bug or need a field that is missing? Open an issue on the [Issues tab](https://apify.com/memo23/opencorporates-scraper/issues) or email muhamed@didovic.dev.

### Additional Services

Need a custom export, a jurisdiction-specific field, scheduled monitoring of a company list, or delivery into your own database? I build tailored versions: muhamed@didovic.dev.

### Explore More Scrapers

- Full list of my actors at [apify.com/memo23](https://apify.com/memo23).

### 🤖 For AI Agents & LLM Apps

Reference for agents calling this actor through the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/opencorporates-scraper`).

**Purpose:** company registry records from OpenCorporates by jurisdiction code or company URL, one row per company.

**Minimal input:**

```json
{ "jurisdictions": ["gb"], "maxItems": 50 }
```

**Lookup input:**

```json
{ "startUrls": ["https://opencorporates.com/companies/us_ca/C0806592"] }
```

**Output fields:** `name`, `companyNumber`, `status`, `incorporationDate`, `dissolutionDate`, `companyType`, `jurisdiction`, `jurisdictionCode`, `registeredAddress`, `registeredAddressLines[]`, `agentName`, `agentAddress`, `industryCodes[]`, `previousNames[]`, `previousCompanyNumbers[]`, `otherIdentifiers[{type,value}]`, `latestAccountsDate`, `annualReturnLastMadeUpDate`, `registryPage`, `officersCount`, `inactiveOfficersCount`, `beneficialOwnersCount`, `beneficialOwners[]`, `directorsOfficers[{name,position,startDate,endDate,isActive,isCorporate,link}]`, `recentFilings[{date,title,url}]`, `dataSource{...}`, `otherAttributes{}`, `loginRequiredFields[]`, `url`, `scrapedAt`.

**Behaviour an agent should know:**

- Always set `maxItems`: one jurisdiction can hold millions of companies. Billing is per row, plus per enriched row when officer enrichment is on.
- Jurisdiction codes are lowercase: `gb`, `fr`, `us_ca`, `ca_on`. `us` means every US state. Unknown codes fail the run within seconds.
- Missing values are `null` or `[]`, never placeholder text.
- Officer names, beneficial owners and incorporation dates come through the built-in officer enrichment: set `includeOfficers: true` (default `false`). Without it the officer counts are still returned.
- Billing: `apify-default-dataset-item` per row; `officer-enrichment` additionally per row that was actually enriched (only when `includeOfficers` is true). Rows that could not be enriched are billed as base rows only.
- No name search. To look up one company, pass its URL in `startUrls`.

***

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by OpenCorporates Ltd. All trademarks are the property of their owners.

Without officer enrichment the actor reads only pages that OpenCorporates shows to any visitor. With officer enrichment it reads what a standard signed-in account can see; it does not bypass authentication or access paid features. You are responsible for making sure your use complies with OpenCorporates' terms of use, data-protection law (GDPR, CCPA and others) and your organisation's own obligations, especially when processing personal data such as officer names.

***

### SEO Keywords

opencorporates scraper, opencorporates api alternative, company registry scraper, company registry data, business registry export, kyb data, company verification, company number lookup, directors and officers data, beneficial owners data, uk company data, companies house data, us secretary of state data, business entity search, registered agent lookup, sic code company list, nace code company list, ein lookup, sec cik lookup, company incorporation date, dissolved companies list, bulk company data, b2b company list by country

# Actor input Schema

## `jurisdictions` (type: `array`):

Jurisdiction codes: a two-letter country (gb, fr, nl, fi) or country_state (us_ca, us_ny, ca_on). A country code alone (us, ca) matches all of its states and provinces.

## `startUrls` (type: `array`):

OpenCorporates company pages, e.g. https://opencorporates.com/companies/gb/05957738. Use this to look up specific companies. Can be combined with jurisdictions.

## `includeOfficers` (type: `boolean`):

Add directors, officers, beneficial owners and incorporation dates to each company record. Charged additionally per enriched record, on top of the base company record. Rows that could not be enriched come with the public fields and no enrichment charge.

## `maxItems` (type: `integer`):

Stop after this many company records. Each record is one billed result (plus the enrichment charge if officers are on).

## `startOffset` (type: `integer`):

Skip this many companies of the jurisdictions above, to continue where an earlier run stopped (e.g. 1000 after a run of 1000). Company URLs are never skipped. The order can change when OpenCorporates updates its listings, so a long-ago offset may repeat or miss some companies.

## `maxConcurrency` (type: `integer`):

How many company pages to load in parallel.

## `recordMaxAgeDays` (type: `integer`):

Companies collected for any run in the last N days are returned at once instead of being loaded again; each row's scrapedAt shows when it was collected. Set 0 to always load fresh data.

## `proxy` (type: `object`):

Leave empty to use the built-in residential proxy.

## Actor input object example

```json
{
  "jurisdictions": [
    "gb"
  ],
  "includeOfficers": false,
  "maxItems": 1000,
  "startOffset": 0,
  "maxConcurrency": 15,
  "recordMaxAgeDays": 30
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `people` (type: `string`):

No description

# 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 = {
    "jurisdictions": [
        "gb"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/opencorporates-scraper").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 = { "jurisdictions": ["gb"] }

# Run the Actor and wait for it to finish
run = client.actor("memo23/opencorporates-scraper").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 '{
  "jurisdictions": [
    "gb"
  ]
}' |
apify call memo23/opencorporates-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/opencorporates-scraper"
        }
    }
}
```

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/ZA66XbUG4iRWJBHsH/builds/Rx7orrKLvxgDMqCV7/openapi.json
