# Czech VAT Payer Check: Reliability & Bank Accounts (`thatmike1/cz-vat-bank-watchlist`) Actor

Check Czech suppliers' VAT reliability status and published bank accounts by DIČ from the official register, with expected-account matching and changes.

- **URL**: https://apify.com/thatmike1/cz-vat-bank-watchlist.md
- **Developed by:** [Michal Pšenčík](https://apify.com/thatmike1) (community)
- **Categories:** Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.00005 / actor start

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

## Czech VAT Payer Check: Reliability & Bank Accounts

Check Czech suppliers by DIČ against the official VAT register of the Czech Financial Administration (Finanční
správa, the public `rozhraniCRPDPH` web service). For each supplier the register finds, you get one check receipt:
VAT subject type, unreliable-payer status and date, tax office code, and every published bank account (standard
Czech accounts and non-standard ones such as foreign IBANs) with its publication dates. Optionally compare each
supplier against the account you expect to pay, and keep a watchlist so each check says whether anything changed
since your last delivered check. Built for accounts-payable teams and bookkeepers who check suppliers before a
payment batch or on a schedule.

### Input

```json
{
    "suppliers": [
        {
            "vatId": "CZ27082440",
            "reference": "supplier-a",
            "expectedAccount": { "kind": "standard", "value": "2171532/0800" }
        },
        {
            "vatId": "CZ26168685",
            "reference": "supplier-b",
            "expectedAccount": { "kind": "standard", "value": "5020019959/5500" }
        }
    ],
    "watchKey": "accounts-payable",
    "maxResults": 100,
    "requestIntervalSeconds": 2
}
```

- `suppliers` (required): 1 to 100 entries. `vatId` is an eight-digit Czech DIČ; spaces and one `CZ` prefix are
  removed, leading zeros are kept. Nine- and ten-digit personal DIČ values are not supported. `reference` is your
  own label (up to 100 characters). `expectedAccount` is optional: `standard` takes `[prefix-]number/bankCode`
  (leading zeros ignored), `nonstandard` takes the published value as the register shows it (spaces removed,
  uppercased). Kinds are never converted into each other. The same DIČ twice is checked once; the same DIČ with a
  different reference or expected account is rejected for all its entries.
- `watchKey` (optional): name a watchlist to keep the last delivered check per supplier between runs. Without it
  every check is `untracked`. Runs that use watch keys must not overlap: start the next one after the previous one
  has finished.
- `maxResults` (default 100): stop after this many stored checks.
- `requestIntervalSeconds` (default 2, 2-60): pause after every register response. Each request checks at most
  two suppliers.

Unknown properties are rejected. An invalid supplier entry is reported in the run summary and the others are
still checked.

### Output

One dataset row per supplier the register found, including suppliers that did not change. Example (accounts
shortened):

```json
{
    "schemaVersion": 1,
    "normalizationVersion": 1,
    "supplierId": "cz-vat:26168685",
    "observationId": "<run id>:cz-vat:26168685",
    "vatId": "CZ26168685",
    "reference": "supplier-b",
    "found": true,
    "subjectType": "PLATCE_DPH",
    "unreliablePayer": false,
    "unreliableSince": null,
    "taxOfficeCode": "13",
    "accounts": [
        {
            "key": "standard:5020019959/5500",
            "kind": "standard",
            "rawValue": "5020019959/5500",
            "prefix": null,
            "number": "5020019959",
            "bankCode": "5500",
            "publishedOn": "2013-04-01",
            "endPublicationOn": null
        }
    ],
    "expectedAccount": { "kind": "standard", "value": "5020019959/5500", "key": "standard:5020019959/5500" },
    "expectedMatch": "published",
    "comparison": "baseline",
    "previousObservedAt": null,
    "changes": {
        "unreliablePayer": null,
        "subjectType": null,
        "unreliableSince": null,
        "taxOfficeCode": null,
        "accountsAdded": [],
        "accountsNoLongerReturned": [],
        "accountMetadataChanged": [],
        "expectedMatch": null
    },
    "fingerprint": "28120fe8887f80a6545222f9fcd9dac8276dee4d6ebd6f988a9e2ce07829f5dd",
    "sourceGeneratedOn": "2026-10-16",
    "observedAt": "2026-10-16T14:40:40.671Z",
    "provenance": {
        "source": "cz_financial_administration_rws",
        "endpoint": "https://mojedane.gov.cz/dpr/axis2/services/rozhraniCRPDPH.rozhraniCRPDPHSOAP",
        "operation": "getStatusNespolehlivySubjektRozsirenyV2",
        "responseSha256": "4615c5ee130999cf375d031744d06257a9df7aaa6cc62866b61f928fdf3001bb",
        "responseSupplierCount": 2
    }
}
```

- `expectedMatch`: `published` (your account is listed without an end-of-publication date), `end_marker_present`
  (listed only with one), `not_listed`, or `not_requested`. An unlisted account is not proof that it is invalid, and
  an end-of-publication marker is not proof that the account was closed.
- `comparison`: `untracked`, `baseline` (first check in this watchlist), `unchanged`, `changed`, or
  `configuration_changed` (you changed the expected account; the expected-match comparison restarts and only real
  register changes are listed). `changes` lists before/after values and sorted account keys. An account in
  `accountsNoLongerReturned` is one the register no longer returns, nothing more.
- Dates from the register are calendar dates (`YYYY-MM-DD`); `observedAt` is a UTC instant. Subject names and
  addresses are never output or stored.

Dataset views: supplier checks, one row per published account, and changes. Export as JSON, CSV or Excel.

The free run summary is the `SUMMARY` record in the run's key-value store: run status, counts, request count and
bytes, whether the spending limit or `maxResults` stopped the run, and one outcome per input entry
(`delivered`, `duplicate`, `not_found`, `error` with a code such as `stale_source_date` or `source_blocked`, or
`not_attempted_cap`). Suppliers the register does not find, invalid entries and all errors are free and are never
written to the dataset.

### Pricing

Pay per event:

- $0.00005 per run start.
- $0.002 per stored supplier check, including unchanged checks.

100 suppliers in one run cost $0.20005. A run where nothing is found, or that fails, costs only the start. Retries
and duplicate entries never add rows.

### Limits and source notes

- The register updates once a day; its maintenance window is 00:00-00:10 Prague time. The Actor makes no requests
  between 00:00 and 00:15 Prague time and accepts an answer only when the register's generation date is today's
  Prague date; otherwise the affected suppliers get a free `stale_source_date` and keep their previous baseline.
  Polling more often than daily does not give fresher data.
- At most 100 suppliers per run, two per request, one request at a time, a 240 s work budget, at most 200 published
  accounts per supplier (more is a free `account_limit` error, never a truncated list).
- Blocks are reported, not worked around: HTTP 403, 429, a challenge page or a redirect stops all further requests
  in the run. A Retry-After is honoured for every later request of the run; one longer than 30 s defers the rest of
  the run. No proxy, login or browser is used.
- Watchlists live in one store per Actor with up to 20 watch keys, 1,000 suppliers in total and 4 MiB of saved
  state. A supplier left out of your input is forgotten after 90 days without a delivered check; one still in your input keeps its
  baseline whatever happens to its check, including an entry rejected as invalid. Delivery is at least once: a crash
  between storing a row and saving its baseline can repeat that change in the next run. A receipt recovered after a
  restart never replaces a newer saved baseline or exceeds state capacity. Stored receipts remain delivered in
  `SUMMARY` even if their baselines cannot be saved; the run fails and stops further delivery.
- This is a data check, not tax advice, and it does not verify who owns an account. You are the controller of any
  personal data you put in your input; the Actor adds none.

### Support

Source: the Czech Financial Administration's register of VAT payers web service
(https://financnisprava.gov.cz/cs/dane/dane-elektronicky/danovy-portal/registr-dph). Report problems through the
Actor's Issues tab with the run ID; the `SUMMARY` record usually says what happened.

# Actor input Schema

## `suppliers` (type: `array`):

1 to 100 suppliers. Each item: <code>vatId</code> (required, eight-digit Czech DIČ, the CZ prefix is optional), <code>reference</code> (optional, your own label, at most 100 characters) and <code>expectedAccount</code> (optional, <code>{"kind": "standard", "value": "\[prefix-]number/bankCode"}</code> or <code>{"kind": "nonstandard", "value": "IBAN or other published value"}</code>). Unknown properties are rejected. Nine- and ten-digit personal DIČ values are not supported.

## `watchKey` (type: `string`):

Optional name (A-Z, a-z, 0-9, \_ or -, up to 64 characters) for a watchlist whose last delivered checks are kept between runs, so each new check says baseline, unchanged, changed or configuration_changed. Leave empty for stateless checks. Runs using watch keys must not overlap.

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

Stop after this many found-supplier checks are stored (1-100).

## `requestIntervalSeconds` (type: `integer`):

Idle time after each register response before the next request (2-60). Each request checks at most two suppliers.

## Actor input object example

```json
{
  "suppliers": [
    {
      "vatId": "CZ27082440",
      "reference": "supplier-a",
      "expectedAccount": {
        "kind": "standard",
        "value": "2171532/0800"
      }
    },
    {
      "vatId": "CZ26168685",
      "reference": "supplier-b",
      "expectedAccount": {
        "kind": "standard",
        "value": "5020019959/5500"
      }
    }
  ],
  "maxResults": 100,
  "requestIntervalSeconds": 2
}
```

# Actor output Schema

## `checks` (type: `string`):

No description

## `summary` (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 = {
    "suppliers": [
        {
            "vatId": "CZ27082440",
            "reference": "supplier-a",
            "expectedAccount": {
                "kind": "standard",
                "value": "2171532/0800"
            }
        },
        {
            "vatId": "CZ26168685",
            "reference": "supplier-b",
            "expectedAccount": {
                "kind": "standard",
                "value": "5020019959/5500"
            }
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("thatmike1/cz-vat-bank-watchlist").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 = { "suppliers": [
        {
            "vatId": "CZ27082440",
            "reference": "supplier-a",
            "expectedAccount": {
                "kind": "standard",
                "value": "2171532/0800",
            },
        },
        {
            "vatId": "CZ26168685",
            "reference": "supplier-b",
            "expectedAccount": {
                "kind": "standard",
                "value": "5020019959/5500",
            },
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("thatmike1/cz-vat-bank-watchlist").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 '{
  "suppliers": [
    {
      "vatId": "CZ27082440",
      "reference": "supplier-a",
      "expectedAccount": {
        "kind": "standard",
        "value": "2171532/0800"
      }
    },
    {
      "vatId": "CZ26168685",
      "reference": "supplier-b",
      "expectedAccount": {
        "kind": "standard",
        "value": "5020019959/5500"
      }
    }
  ]
}' |
apify call thatmike1/cz-vat-bank-watchlist --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,thatmike1/cz-vat-bank-watchlist"
        }
    }
}
```

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/wH8haXFY6cumf2T7Z/builds/ucFN3vcKNC0Hw6ZrE/openapi.json
