# Thai Company Check (VAT, DBD & Gov Contracts by Tax ID) (`chatuporn/thai-company-check`) Actor

Check Thai companies by 13-digit tax ID or name: VAT registration, branches and addresses from the Revenue Department's open data, legal form and registration year from the ID, DBD registration/dissolution and government contracts. For KYC, supplier onboarding and AI agents.

- **URL**: https://apify.com/chatuporn/thai-company-check.md
- **Developed by:** [Chatuporn Duangthong](https://apify.com/chatuporn) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / 1,000 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/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

## Thai Company Check: VAT, DBD and government contracts by tax ID

Look up Thai companies by **13-digit tax ID** (เลขประจำตัวผู้เสียภาษี, the same number as the DBD juristic registration number) or by **company name**. Each query returns:

- **VAT registration**: whether the company is an active VAT registrant, the VAT approval date, and every registered branch with its address as published by the Revenue Department (กรมสรรพากร).
- **What the ID itself says**: legal form (company limited, public company, limited partnership …), year of registration, registration office code. The check digit is validated before anything is looked up.
- **DBD events**: registration date, registered capital, business objective, and dissolution date, for companies registered or dissolved since January 2022 (กรมพัฒนาธุรกิจการค้า).
- **Government contracts**: number and total value (THB) of Thai government e-GP contracts won, by fiscal year, with the most recent contracts.
- **Sources and data dates** for every answer.

Typical uses: supplier onboarding, KYC-lite checks of counterparties, checking a buyer's tax ID and branch number before issuing a tax invoice, cleaning CRM or ERP vendor lists, and AI agents (MCP) that need a quick and cheap "does this Thai company exist and is it VAT-registered?" tool.

Lookups read a pre-built index, so they are fast (well under a second per company once the Actor runs) and do not touch government websites at query time.

### Input

| Field | What it does |
|---|---|
| `taxIds` | List of 13-digit tax IDs. Dashes and spaces are fine (`0-1075-44000-10-8`). |
| `companyNames` | List of Thai company names. `บริษัท`, `จำกัด`, `(มหาชน)`, `บจ.`, `หจก.` are ignored. |
| `maxMatchesPerName` | How many companies to return per name (default 3). |
| `minNameScore` | Minimum match score for names (default 0.7). |
| `maxBranches` | Branches per company in the output (default 10, head office first). `branchCount` always shows the total. |
| `includeDbd`, `includeGovContracts` | Turn the DBD and contract blocks on or off (default on). |

Example:

```json
{
  "taxIds": ["0107544000108", "0107536000102"],
  "companyNames": ["ซีพี ออลล์"],
  "maxMatchesPerName": 3
}
```

### Output

One dataset item per tax ID, and one item per matched company for each name query.

```json
{
  "query": "0107544000108",
  "queryType": "taxId",
  "status": "found",
  "taxId": "0107544000108",
  "name": "บริษัท ปตท. จำกัด (มหาชน)",
  "legalForm": "public_company_limited",
  "registeredYearBE": 2544,
  "registeredYearCE": 2001,
  "vatRegistered": true,
  "vatRegisteredDate": "2001-10-01",
  "branchCount": 120,
  "headOffice": {"branchNo": "0", "isHeadOffice": true, "address": "เลขที่ 555 ถนนวิภาวดีรังสิต แขวงจตุจักร เขตจตุจักร กรุงเทพมหานคร 10900", "addressParts": {"...": "..."}, "vatApprovedDate": "2001-10-01"},
  "branches": ["..."],
  "dbd": null,
  "dissolved": null,
  "govContracts": {"contracts": 412, "totalThb": 1234567890.0, "fiscalYearsBE": [2565, 2566, 2567, 2568], "byFiscalYear": {"...": "..."}, "matchedBy": "taxId", "recentContracts": ["..."]},
  "sources": ["..."],
  "indexBuiltAt": "2026-11-02T14:30:00+00:00"
}
```

(Values above are illustrative.)

`status` is one of:

- `found`: the company is in at least one source. `vatRegistered: false` means it is known from DBD or e-GP data but is not on the current VAT-registrant list.
- `not_found`: the ID is valid but is in none of the sources. The company may not be VAT-registered (turnover under 1.8 million THB), may have deregistered, or may have registered after the VAT file date.
- `invalid_checksum` or `invalid_format`: the ID is mistyped. **Not charged.**
- `not_juristic`: a personal tax ID (see below). **Not looked up, not charged.**
- `name_too_short`: the name has fewer than two letters once legal-form words are removed. **Not charged.**

`dbd: null` does not mean that the company is not registered. The DBD block only covers companies registered or dissolved since January 2022.

#### Name search

Names are normalized (legal-form words, spaces and punctuation removed) and matched **from the beginning of the name**. `ซีพี ออลล์` finds `บริษัท ซีพี ออลล์ จำกัด (มหาชน)`, but `ออลล์` alone does not. The score is 1 for the same name, 0.6–0.95 for names that start with your query, and lower for near spellings. Names are in Thai as registered; most Thai companies have no English name in these sources.

### Companies only (PDPA)

The VAT-registrant file also lists natural persons. Their tax ID is their national ID number, so their entries are personal data under Thailand's Personal Data Protection Act. This Actor **keeps only juristic persons**:

- tax IDs that start with `0`
- excluding `0991…` (people without a Thai ID, and estates) and `0992…` (unregistered partnerships and groups of persons)
- excluding entries whose name is a person's name

Personal tax IDs in the input are recognized and answered with `not_juristic`, without any lookup.

### Data sources and freshness

| Source | Publisher | Licence | Freshness |
|---|---|---|---|
| [VAT registrants (ภ.พ.20 addresses)](https://data.rd.go.th/dataset/vat_taxpayeraddress_10_01) | Revenue Department | Open Data Common | Two files. Provinces file: last updated Aug 2026. **Bangkok file: last updated Jul 2025.** The RD updates them irregularly. |
| [DBD new and dissolved juristic persons](https://opendata.dbd.go.th) | Department of Business Development | Open Data Common | Monthly, since Jan 2022 |
| [e-GP procurement contracts](https://data.go.th) | Comptroller General's Department | Open Data Common | Fiscal years 2565–2568 |

Each item's `sources` block gives the exact data dates used, and `indexBuiltAt` gives the time of the last rebuild. The index is rebuilt when a source publishes a new file.

Things to know:

- A company with its head office in Bangkok that registered for VAT after July 2025 may be missing until the Revenue Department refreshes the Bangkok file. A company that deregistered after a file's date may still show as registered.
- The VAT list holds active registrants only. Absence is not proof that a company does not exist.
- Government contracts are matched by tax ID. For fiscal years whose files lost the tax IDs (most of FY2565–2567), they are matched by the exact registered name, and only when that name belongs to a single company. In that case `matchedBy` is `"name"`.
- This is an information service built from open government data. It is not an official certificate. For legal certainty, check the RD VAT service or a DBD company affidavit.

Attribution: data from กรมสรรพากร, กรมพัฒนาธุรกิจการค้า and กรมบัญชีกลาง, used under the Open Data Common licence.

### Pricing

Pay per result. One `company` event is charged for each answered lookup: a found company, or a valid ID that is not found. Mistyped IDs and personal IDs are free. For name queries, each returned match is one result.

### Using it from AI agents (MCP)

Add the Actor to the Apify MCP server (`actors=<username>/thai-company-check`). Input: `{"taxIds": ["..."]}`. The output is compact JSON with `status`, `name`, `vatRegistered` and `headOffice.address`, which an agent can read directly.

# Actor input Schema

## `taxIds` (type: `array`):

13-digit tax IDs of Thai juristic persons (= DBD registration numbers), e.g. 0107544000108. Dashes and spaces are ignored. The check digit is validated first; personal tax IDs are not looked up.

## `companyNames` (type: `array`):

Thai company names as registered, e.g. 'ปตท.' or 'บริษัท ซีพี ออลล์ จำกัด (มหาชน)'. Words like บริษัท / จำกัด / (มหาชน) are ignored. Names match from their beginning; each query returns the best matches with a score.

## `maxMatchesPerName` (type: `integer`):

How many companies to return for each name query (best score first). Each returned company is one result.

## `minNameScore` (type: `string`):

Only return name matches scoring at least this (0.3 to 1). 1 = same name; a name that starts with your query scores 0.6 to 0.95.

## `maxBranches` (type: `integer`):

How many VAT-registered branches (head office first) to include per company, with addresses as published. branchCount always gives the total.

## `includeDbd` (type: `boolean`):

Add the DBD record (registration date, capital, objective, dissolution date) when the company was registered or dissolved since January 2022.

## `includeGovContracts` (type: `boolean`):

Add a summary of Thai government e-GP contracts won (count, total THB, fiscal years, recent contracts) when the company appears in the e-GP data.

## `refreshIndex` (type: `boolean`):

Publisher only. Ignored without the admin key.

## `forceRefresh` (type: `boolean`):

Publisher only.

## `indexStore` (type: `string`):

Publisher only. The key-value store the refresh writes to (thai-company-check-index).

## `adminKey` (type: `string`):

Publisher only.

## Actor input object example

```json
{
  "taxIds": [
    "0107544000108",
    "0107536000102"
  ],
  "maxMatchesPerName": 3,
  "minNameScore": "0.7",
  "maxBranches": 10,
  "includeDbd": true,
  "includeGovContracts": true,
  "refreshIndex": false,
  "forceRefresh": false
}
```

# Actor output Schema

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

Every item of the run as JSON, with branches, DBD data, contracts and sources.

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

Table view: status, tax ID, name, legal form, VAT status, branches, head-office address, DBD and contracts.

# 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 = {
    "taxIds": [
        "0107544000108",
        "0107536000102"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("chatuporn/thai-company-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 = { "taxIds": [
        "0107544000108",
        "0107536000102",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("chatuporn/thai-company-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 '{
  "taxIds": [
    "0107544000108",
    "0107536000102"
  ]
}' |
apify call chatuporn/thai-company-check --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,chatuporn/thai-company-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/eF2SxIk4kdUCWh7pl/builds/bYbhASg2puAoxIr2C/openapi.json
