# Czech Public Contract Amendments - Registr smluv Monitor (`thatmike1/cz-contract-amendments`) Actor

Amendments (dodatky) and new versions of Czech public contracts from the official Registr smluv open-data dumps, with original values, changed fields and IČO filters.

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

## Pricing

from $0.005 / 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 Public Contract Amendments – Registr smluv

Monitor Czech public contract amendments (dodatek, dodatky) and corrected versions of published smlouvy. This actor reads only the official **registr smluv** open-data daily XML dumps at [data.smlouvy.gov.cz](https://data.smlouvy.gov.cz/). It emits a billable event for each linked amendment or new version matching your publisher or supplier IČOs, with the linked original or previous version alongside it.

Useful for Czech bid consultants and supplier-risk teams monitoring public buyers and suppliers daily. No API key or proxy is required.

### Quick start

```json
{
    "icos": ["27523543"],
    "fromDate": "2026-10-14",
    "toDate": "2026-10-14",
    "eventTypes": ["amendment", "new_version"],
    "resolveOriginals": true,
    "maxEvents": 10,
    "includeNaturalPersonNames": false
}
```

Omit the dates for the last **two closed publication days** listed in the live index, including weekends. The default input `{}` scans all IČOs and delivers at most ten events. It uses real live data, so an upstream outage fails the run instead of fabricating empty results. A run can be empty when the source has no qualifying events.

### Inputs

| Field                       | Default              | Meaning                                                                                                                              |
| --------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `icos`                      | `[]`                 | Eight-digit string IČOs, preserving leading zeros. Matches the publisher or any contract party. Empty means all records.             |
| `fromDate`, `toDate`        | Last two closed days | Inclusive publication dates, `YYYY-MM-DD`. Supplying just one means that day only. Explicit ranges can include the open current day. |
| `eventTypes`                | Both types           | `amendment` and/or `new_version`.                                                                                                    |
| `resolveOriginals`          | `true`               | Resolve the linked original or older version on its first publication day. Disable for faster metadata-only events.                  |
| `maxEvents`                 | `10`                 | Maximum delivered rows. `0` explicitly removes the limit.                                                                            |
| `includeNaturalPersonNames` | `false`              | Opt in to FO, ZFO and PFO party names.                                                                                               |
| `watchName`                 | Unset                | Persist a named watch and suppress already delivered version/event pairs for 60 days.                                                |

For a daily schedule, use a stable `watchName` and overlapping date windows, or keep the default two-day window. A separate named key-value store retains each watch across runs; default run stores do not provide cross-run state. Only successfully stored dataset rows enter the watch state. Platform spending limits and failed pushes therefore cannot mark undelivered rows as seen. Run the same watch sequentially: concurrent runs of one watch can race. Watches are scoped to your Apify account and this actor's watch-store prefix. Use distinct names for distinct filters; changing filters does not reset a watch. After 60 days an old event is eligible again.

### Output and changes

Each default-dataset row has `eventType`, `contractId`, `versionId`, `url`, `publishedAt`, `publisher`, `parties`, `subject`, `valueWithoutVat`, `valueWithVat`, `currency`, `foreignValue`, `priceNotStated`, `concludedOn`, `contractNumber`, `attachmentCount`, `isCurrentVersion`, `sourceDump` and `observedAt`.

Identifiers, amounts and missing-price reasons remain strings, preserving source precision and leading zeros. Unavailable scalar fields are `null`; missing values are never converted to zero. Dates retain the registry's publication offset.

- **`amendment`**: a linked `navazanyZaznam` record whose contract is first published on that day (its contract ID exceeds the previous publication day’s maximum), whether or not its subject says “dodatek”. `original` contains the linked contract snapshot, including `idSmlouvy`, `idVerze`, its own URL and publisher. The link is a **contract ID**, not a version ID: the actor never outputs the registry's misleading outer original URL.
- **`new_version`**: a version of a contract first published on an earlier publication day. `previous` contains the newest older version across the contract’s first-publication day and all daily dumps already loaded during this run. `previousScope` is `"first_publication_day"` when the selected version comes from the first day, or `"scanned_window"` when it comes from another already loaded day (including a cached day outside the requested window). Multiple corrections on one scanned day therefore compare with the newest earlier correction. Intermediate days that have not been loaded are **not downloaded to search for versions in v1**, so the result is the newest available predecessor rather than a guarantee of complete history. A correction of a linked contract retains its `linkedContractId` and produces only this event type. `changedFields` and `changes` report old/new subjects, values, currency, conclusion date, contract number, parties (by IČO and name, ignoring order), and attachments (by hash, ignoring order). `hodnotaBezDph` is included as a source-name alias for `valueWithoutVat` in both change objects and field lists.

A correction of an older linked contract produces one `new_version` row and is never re-reported or billed as a fresh amendment. When only `amendment` is selected, such corrections are excluded. New contracts without a link produce no rows. A same-day correction to a contract first published that same day is outside the earlier-day `new_version` definition.

`originalLookup` or `previousLookup` is `resolved`, `not_found`, `error`, or `disabled`. Unresolved snapshots are `null` with a reason; `not_found` is distinct from an upstream HTTP error or a transport failure (`error` reasons include their error type/status). Disabling lookups leaves `changedFields` empty rather than claiming there were no changes. The linked snapshot is the latest version found on the linked contract's first-publication day; it is not guaranteed to be its current version.

The free `SUMMARY` record in the **default key-value store** reports scanned publication days, dump URLs, generation times and record counts; matching records; delivered event counts by type; lookup outcomes; events cut by `maxEvents`; watch deduplication; requests and downloaded bytes. If the platform spending budget is exhausted, scanning stops immediately; `stopReason` is `spending_budget_exhausted` and later days are listed as skipped. Otherwise `stopReason` is `null`. It is never a billable dataset row. A missing or broken daily dump fails the run and preserves the partial summary; it is never treated as an empty day. Index-level failures fail before a summary can be produced.

### Source, performance and coverage

Requests are sequential with at least one second between starts, including retries. The shared HTTP client retries transport failures, HTTP 429 and 5xx with up to seven retries, exponential backoff growing to 30 seconds, and `Retry-After` (which can require a longer wait). Full dumps have a 120-second per-attempt timeout. The actor never requests the registry web application, linked HTML pages or attachment files. URLs to those pages are output metadata only.

The daily index begins in 2017. To resolve an original, the actor searches the maximum contract ID in the first 64 KiB of daily dumps, interpolating publication-order IDs between observed bounds with regular binary steps, then checks surrounding days for late-day publications. Empty prefixes are skipped; a non-monotonic first record does not decide the search. Contracts before the daily archive or removed by the registry can be unresolved. **Assumption: Registr smluv assigns contract IDs in publication order.** Both the amendment test (a contract ID above the previous publication day's maximum) and the original search rely on it. It held on every one of the 120 daily dumps checked on 16 October 2026 (18 June to 15 October: each day's highest ID was above every earlier day's, and no day was empty). If a day ever broke the order, for example a day holding only corrections to old contracts, the next day's correction of an older linked contract could be reported (and billed) as an `amendment` instead of a `new_version`, and an original published before that day could come back as `originalLookup: not_found`. Both stay visible in the row and in the summary's lookup counts.

Previous-version lookup combines the first-publication day with matching versions from daily dumps already loaded in this run. A lightweight contract-ID index locates matching disk caches; consulting them adds no network requests. No extra intermediate days are downloaded for version history. Full dumps are cached **on disk** for the run, with only one parsed dump retained by the source. A broad IČO filter or date window can still need many requests and substantial disk space. The default runtime is 1024 MB / 3600 seconds. `maxEvents` limits rows and original lookups, not the cost of scanning the requested publication window or counting omitted events. Exhausting the platform spending budget stops further scanning.

The current open daily dump is excluded by default, and explicitly requested open days can grow between runs. A default two-day schedule is not a historical backfill. Older changes outside the window are not emitted automatically.

### Personal data and your responsibilities

The registry's open metadata can contain personal data. You become a data controller for your use of it and must establish your own lawful basis, retention, access controls and handling of data-subject requests. You must remove data that the registry later makes inaccessible, including copies exported from Apify. Open data is not an exemption from those duties.

This actor never outputs addresses or `schvalil` (signatory names). By default FO (natural person), ZFO (foreign natural person) and PFO (sole trader) parties expose **only `ico` and `kind`**. Names and recipient flags for those parties require `includeNaturalPersonNames: true`; this setting also applies to original/previous snapshots and change values. Publisher metadata and other registry free-text fields can still contain personal data, so review downstream use. Run caches contain raw public XML until cleanup at run completion; watch stores contain only version/event identifiers and delivery timestamps.

### Pricing

**$0.008 per delivered event**, plus **$0.005 per actor start**. These are the platform's built-in `apify-default-dataset-item` and `apify-actor-start` events. Ten delivered events cost $0.085 including the start fee, with usage included when configured as Pay per event. Empty runs incur the start fee. The summary is free. Spending caps can reduce the number of stored rows.

### Version 1 scope

Withdrawals (“znepřístupnění”) are **not detected**: the registry deletes all versions of a withdrawn contract from the dumps. Withdrawal monitoring needs a stored baseline of the user's contracts and is a likely v2 feature. Users remain responsible for deleting inaccessible records.

Attachments are counted only in contract snapshots. Changes expose comparison hashes but no file contents, names or download links. There is no attachment download, OCR, document-text extraction, legal interpretation, historical completeness guarantee, or removal feed.

# Actor input Schema

## `icos` (type: `array`):

Eight-digit publisher or party IČOs, including leading zeros. Empty means all records; maxEvents still applies.

## `fromDate` (type: `string`):

YYYY-MM-DD, inclusive. Omit both dates for the last two closed daily dumps. One supplied date means that day only.

## `toDate` (type: `string`):

YYYY-MM-DD, inclusive. Explicit date ranges may include the growing current-day dump.

## `eventTypes` (type: `array`):

A linked contract first published that day is an amendment. A correction of an older linked contract is one new_version event, never a fresh amendment.

## `resolveOriginals` (type: `boolean`):

Find the linked original or newest older version across the first-publication day and daily dumps already loaded in this run. No extra intermediate days are downloaded. Adds requests for original resolution; failed lookups retain an explicit status and reason.

## `maxEvents` (type: `integer`):

Default 10 keeps the scheduled default run inexpensive. Zero explicitly removes the limit. Skipped rows are never billed.

## `includeNaturalPersonNames` (type: `boolean`):

Opt in to names for FO, ZFO and PFO parties. By default these parties expose only ico and kind. Addresses and signatories are never output.

## `watchName` (type: `string`):

Optional stable watch identifier (1–100 letters/digits/spaces/\_/-). A named key-value store remembers stored version/event pairs for 60 days. Run the same watch sequentially.

## Actor input object example

```json
{
  "icos": [],
  "eventTypes": [
    "amendment",
    "new_version"
  ],
  "resolveOriginals": true,
  "maxEvents": 10,
  "includeNaturalPersonNames": false
}
```

# Actor output Schema

## `events` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("thatmike1/cz-contract-amendments").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("thatmike1/cz-contract-amendments").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 '{}' |
apify call thatmike1/cz-contract-amendments --silent --output-dataset

```

## MCP server setup

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

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/MXu00H8pfxORLeGGp/builds/6MYMPAnVjQqxHuLg8/openapi.json
