# Company Verification & Counterparty Check (KYB-lite) (`ventura_workalong/counterparty-check`) Actor

Is this business real? Verify a company in one call: domain age, SSL & DNS, GLEIF LEI, US state registry status, EU VAT (VIES) and OFAC/US screening-list possible matches, plus a plain-language consistency summary. Official open data only. $0.03 per check.

- **URL**: https://apify.com/ventura_workalong/counterparty-check.md
- **Developed by:** [Ventura WorkAlong](https://apify.com/ventura_workalong) (community)
- **Categories:** Lead generation, Developer tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 company checkeds

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

## Company Verification & Counterparty Check (KYB-lite)

**Is this business real?** Counterparty Check verifies a company in one call, using **official and open public sources only**. For each company you get:

1. **Domain signals** (when you give a website): domain age from RDAP (the official WHOIS successor), DNS and email (MX, SPF, DMARC), SSL certificate validity and the organization named on it, and a security-headers grade.
2. **GLEIF LEI record**: the Legal Entity Identifier, legal name, entity and registration status, jurisdiction and registration authority ID. You can look it up by LEI or by best name match. Data is CC0 from GLEIF.
3. **US screening lists**: possible name matches against the **OFAC SDN list** and the **US Consolidated Screening List** (BIS Entity List, Denied Persons, Unverified, Military End User, State ITAR debarred, nonproliferation, OFAC SSI/CMIC and more). Each match comes with a score, the list it's on, its programs and a link to the source. Every match is labeled **"possible match, verify"**.
4. **EU VAT validation** (when you give a VAT number): checks validity in the European Commission's **VIES** service and whether the registered name matches yours.
5. **US state registry status** (when you give a state): entity status, type and formation date from official state open-data registries. Supported states: **Colorado, Connecticut, New York and Pennsylvania**.
6. **Consistency summary**: plain-language observations, each marked `pass`, `flag`, `review` or `info`. Examples: "Domain registered 35 years ago", "Active LEI ...", "1 possible name match on SDN, verify". **There is no risk score.**

**$0.03 per company checked.** Invalid input is free. So is any check where the screening lists couldn't be loaded or no source answered.

> **Not a regulated KYC/AML/sanctions screening service.** It does not identify people or beneficial owners, and it does not decide anything for you. Screening results are fuzzy name matches on organization entries. Treat each one as a lead to verify against the official list, not a determination. If you have legal screening obligations, use a licensed provider.

### How to verify a company

1. In **Companies**, add one JSON object per company. `name` is required; add any of `domain`, `country`, `state`, `vatNumber` and `lei` that you know. More fields mean more checks.
2. Click **Start**. The **Overview** table shows the consistency headline, domain age, SSL, LEI, state status, VAT validity and screening matches for each company.
3. Export the results to CSV or Excel, or call the Actor from an AI agent over MCP or the API.

```json
{
  "companies": [
    {"name": "Microsoft Corporation", "domain": "microsoft.com", "country": "US", "state": "NY"},
    {"name": "Google Ireland Limited", "domain": "google.ie", "country": "IE", "vatNumber": "IE6388047V"},
    {"name": "Apple Inc.", "domain": "apple.com", "lei": "HWUPKR0MPOU8FGXBT394"}
  ]
}
```

### Use cases

- **AI agents that transact:** before an agent pays an invoice, onboards a supplier or ships an order, it can ask "is this counterparty real and consistent?" and get one structured answer.
- **Vendor and supplier onboarding:** check that the website, LEI, VAT number and state registration all point to the same live entity.
- **Marketplace and B2B sign-up review:** catch domains registered last week, invalid VAT numbers, dissolved entities and screening-list name matches worth a human look.
- **Data enrichment:** add LEI, jurisdiction, entity status and formation date to a list of companies.

### Input

| Field | What it does | Default |
|---|---|---|
| `companies` | List of `{name, domain?, country?, state?, vatNumber?, lei?}`. A plain string counts as a name. Up to 1,000 per run. | required |
| `includeDomainSignals` | RDAP age, DNS/MX, SSL and headers (needs `domain`) | true |
| `includeLei` | GLEIF LEI lookup (by `lei`, or by name) | true |
| `includeScreening` | OFAC SDN + Consolidated Screening List name matching | true |
| `includeVat` | EU VIES validation (needs `vatNumber`) | true |
| `includeStateRegistry` | State registry lookup (needs `state`: CO, CT, NY or PA) | true |
| `screeningMinScore` | Minimum name similarity for a screening match (70–100). Lower values catch more variants and more false positives. | 88 |
| `respectRobotsTxt` | Skip the homepage headers request when robots.txt disallows it | true |
| `maxConcurrency` | Companies checked in parallel (1–5). Each source keeps its own rate limit. | 3 |

The price is the same however many sources a company has. Turning sources off only makes runs faster.

### Output (one item per company)

Real output for Microsoft (2026-10-09, shortened):

```json
{
  "name": "Microsoft Corporation", "status": "ok",
  "consistency": {
    "headline": "8 consistent, 0 flag(s), 0 to review, 0 info",
    "observations": [
      {"check": "domainAge", "result": "pass", "detail": "Domain registered 35 years ago."},
      {"check": "sslOrganization", "result": "pass", "detail": "SSL certificate is issued to 'Microsoft Corporation' (name similarity 100)."},
      {"check": "lei", "result": "pass", "detail": "Active LEI INR2EJN1ERAN0W5ZP974 for 'MICROSOFT CORPORATION' (US-WA)."},
      {"check": "stateRegistry", "result": "pass", "detail": "NY registry: 'MICROSOFT CORPORATION' (FOREIGN BUSINESS CORPORATION), listed as active, since 1993-10-29."},
      {"check": "screening", "result": "pass", "detail": "No organization-name matches at score >= 88 on OFAC SDN, US Consolidated Screening List."}
    ]
  },
  "domain": {"status": "ok", "domain": "microsoft.com", "summary": {"registrar": "MarkMonitor Inc.", "createdAt": "1991-05-02T04:00:00Z", "ageDays": 12944, "emailProvider": "Microsoft 365", "dmarcPolicy": "reject", "sslValid": true, "sslOrganization": "Microsoft Corporation"}},
  "lei": {"status": "found", "match": {"lei": "INR2EJN1ERAN0W5ZP974", "legalName": "MICROSOFT CORPORATION", "entityStatus": "ACTIVE", "registrationStatus": "ISSUED", "jurisdiction": "US-WA", "registeredAs": "600 413 485", "matchScore": 100, "url": "https://search.gleif.org/#/record/INR2EJN1ERAN0W5ZP974"}},
  "screening": {"status": "ok", "minScore": 88, "possibleMatches": 0, "matches": [], "listsChecked": {"OFAC SDN": {"status": "ok", "entries": 10018}, "US Consolidated Screening List": {"status": "ok", "entries": 3825}}},
  "stateRegistry": {"status": "found", "state": "NY", "match": {"entityId": "1768283", "name": "MICROSOFT CORPORATION", "entityType": "FOREIGN BUSINESS CORPORATION", "statusClass": "active", "formationOrRegistrationDate": "1993-10-29"}, "coverage": "active", "license": "NY Open Data terms of use"},
  "sourcesOk": ["domain", "lei", "screening", "stateRegistry"], "sourcesFailed": [], "error": null
}
```

A screening match looks like this (real, for "Banco Nacional de Cuba"):

```json
{"label": "possible match, verify", "score": 100, "matchedName": "BANCO NACIONAL DE CUBA", "matchedOn": "name",
 "listedName": "BANCO NACIONAL DE CUBA", "list": "SDN", "listName": "OFAC Specially Designated Nationals (SDN) List",
 "programs": ["CUBA"], "entryId": "306", "sourceUrl": "https://sanctionssearch.ofac.treas.gov/"}
```

- `status`: `ok` is charged. `invalid_input` and `failed` are free.
- If one source fails (for example, a VIES member-state service is down), the others still return. `sourcesFailed` and `error` say which source failed and why.

### Sources, terms and limits

| Source | Data | Terms | How we use it |
|---|---|---|---|
| RDAP (IANA bootstrap → registries) | Domain registration | Registry terms; some, e.g. Verisign, limit high-volume use | 1 request/second per registry, at most 2,000 per run. Registrant contacts are never returned |
| GLEIF API | LEI records | **CC0** (LEI Data Terms of Use) | No key needed; about 1 request/second |
| OFAC Sanctions List Service | SDN.CSV, ALT.CSV | US government work, public domain | Downloaded once per run |
| trade.gov Consolidated Screening List | Bulk JSON | US government work, public domain; the bulk file needs no key | Downloaded once per run. Its SDN copy is used only if the OFAC file fails |
| EU VIES REST API | VAT validity | European Commission. For checks that support your own VAT compliance; no registers, no republishing, no lookups of individuals | Only VAT numbers you supply; 1 request/second |
| data.colorado.gov `4ykn-tg5h` | CO entities, all statuses | Public Domain | Entity columns only |
| data.ct.gov `n7gp-d28j` | CT entities, all statuses | Public Domain | Entity columns only |
| data.pa.gov `xvd7-5r2c` | PA current registrations | Public Domain (U.S. Government) | Entity columns only, de-duplicated |
| data.ny.gov `n9v6-gdp6` | NY active corporations | NY Open Data terms (commercial use allowed) | Entity columns only |

**What it doesn't do.** We don't scrape state search portals. We don't return people, so no officers, owners, registered agents, chairmen, or addresses of individuals. We don't search news or adverse media, and we don't check beneficial ownership.

- **Screening** uses organization entries only. Individuals, vessels and aircraft are skipped, and so are untyped entries that look like people.
- **Personal names are never output.** Sole-proprietor LEIs are dropped. A VIES name that doesn't look like an organization is withheld; only its similarity score is returned.
- **NY and PA** publish active or current entities only, so "not found" there doesn't mean inactive.
- **Name matching** ignores case, accents, punctuation and legal forms (Inc, LLC, GmbH...). Generic words alone ("Trading", "Electronics") never make a match.
- **No risk score.** A check full of `pass` means the public sources are consistent with each other. It does not mean the company is safe.

### FAQ

#### Is this a sanctions or KYC compliance tool?

No. It's a fast, cheap, explainable consistency check built on public data. Screening hits are possible matches for a human to verify on the official list. Regulated entities should use a licensed screening provider.

#### Which US states are supported?

Colorado, Connecticut, New York and Pennsylvania: the states that publish their business registry as official open data that allows reuse. We'll add more states as they publish open data. We will not scrape portals that forbid automation.

#### Do I need an API key?

No. Every source used here is keyless.

#### Why was a check not charged?

The input was invalid (no name, or a malformed LEI), the screening lists couldn't be downloaded, or no source answered. You only pay for completed checks.

#### Can AI agents call it?

Yes. Use it through Apify's MCP server (`mcp.apify.com`) or the WorkAlong Data Tools listing in the official MCP Registry. One call returns one structured answer per company. See https://workalong.app/data-tools.

### Related tools by WorkAlong

- [Secretary of State Business Search & LLC Lookup](https://apify.com/ventura_workalong/us-state-business-registry-search): just the state registry, searchable by name, entity ID or formation date in CO, CT, NY and PA, $0.003 per record.
- [Bulk WHOIS Domain Lookup](https://apify.com/ventura_workalong/domain-lookup-bundle): the domain section on its own, $0.003 per domain.
- [Tech Stack Detector](https://apify.com/ventura_workalong/tech-stack-detector): what a website is built with.

# Actor input Schema

## `companies` (type: `array`):

One object per company. `name` is required; add whatever else you know: `domain` (website), `country` (ISO-2, e.g. US, DE), `state` (US state, e.g. CO, CT, NY, PA), `vatNumber` (EU VAT, e.g. IE6388047V) and `lei`. A plain string is treated as a name.

## `includeDomainSignals` (type: `boolean`):

When a domain is given: registration age (RDAP, no personal contacts), DNS/MX/SPF/DMARC, SSL validity and a security-headers grade.

## `includeLei` (type: `boolean`):

Legal Entity Identifier record from GLEIF (by LEI, or best name match): legal name, entity and registration status, jurisdiction.

## `includeScreening` (type: `boolean`):

Fuzzy organization-name matching against the OFAC SDN list and the US Consolidated Screening List. Results are possible matches to verify, not determinations.

## `includeVat` (type: `boolean`):

When a VAT number is given: validity in the EU VIES system. Addresses are never returned.

## `includeStateRegistry` (type: `boolean`):

When `state` is given: entity status from official open-data registries. Supported: CO, CT (all statuses), NY, PA (active/current entities only).

## `screeningMinScore` (type: `integer`):

Minimum name similarity (70-100) to report a possible screening-list match. Lower finds more variants and more false positives.

## `respectRobotsTxt` (type: `boolean`):

Skip the homepage request for the security-headers check if robots.txt disallows it.

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

Companies checked in parallel. Each source keeps its own polite rate limit regardless.

## Actor input object example

```json
{
  "companies": [
    {
      "name": "Microsoft Corporation",
      "domain": "microsoft.com",
      "country": "US",
      "state": "NY"
    },
    {
      "name": "Google Ireland Limited",
      "domain": "google.ie",
      "country": "IE",
      "vatNumber": "IE6388047V"
    },
    {
      "name": "Apple Inc.",
      "domain": "apple.com",
      "country": "US",
      "lei": "HWUPKR0MPOU8FGXBT394"
    }
  ],
  "includeDomainSignals": true,
  "includeLei": true,
  "includeScreening": true,
  "includeVat": true,
  "includeStateRegistry": true,
  "screeningMinScore": 88,
  "respectRobotsTxt": true,
  "maxConcurrency": 3
}
```

# Actor output Schema

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

All results from this run, one item per input company, in the default dataset.

# 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 = {
    "companies": [
        {
            "name": "Microsoft Corporation",
            "domain": "microsoft.com",
            "country": "US",
            "state": "NY"
        },
        {
            "name": "Google Ireland Limited",
            "domain": "google.ie",
            "country": "IE",
            "vatNumber": "IE6388047V"
        },
        {
            "name": "Apple Inc.",
            "domain": "apple.com",
            "country": "US",
            "lei": "HWUPKR0MPOU8FGXBT394"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ventura_workalong/counterparty-check").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 = { "companies": [
        {
            "name": "Microsoft Corporation",
            "domain": "microsoft.com",
            "country": "US",
            "state": "NY",
        },
        {
            "name": "Google Ireland Limited",
            "domain": "google.ie",
            "country": "IE",
            "vatNumber": "IE6388047V",
        },
        {
            "name": "Apple Inc.",
            "domain": "apple.com",
            "country": "US",
            "lei": "HWUPKR0MPOU8FGXBT394",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ventura_workalong/counterparty-check").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 '{
  "companies": [
    {
      "name": "Microsoft Corporation",
      "domain": "microsoft.com",
      "country": "US",
      "state": "NY"
    },
    {
      "name": "Google Ireland Limited",
      "domain": "google.ie",
      "country": "IE",
      "vatNumber": "IE6388047V"
    },
    {
      "name": "Apple Inc.",
      "domain": "apple.com",
      "country": "US",
      "lei": "HWUPKR0MPOU8FGXBT394"
    }
  ]
}' |
apify call ventura_workalong/counterparty-check --silent --output-dataset

```

## MCP server setup

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

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/wMQpY4ablNcUJZDWH/builds/nKuBEphSpK2PXjb1c/openapi.json
