# Slovakia Financial Statements API & Filing Monitor (`automa-flow/slovakia-financial-statements-api-filing-monitor`) Actor

Slovakia financial statements scraper API for official RÚZ filings. Export full filing histories and structured report tables by IČO, consume incremental changes, or monitor up to 500 companies for new statements. No browser, proxy, login, or PDF parsing.

- **URL**: https://apify.com/automa-flow/slovakia-financial-statements-api-filing-monitor.md
- **Developed by:** [Vadim Bezrukov](https://apify.com/automa-flow) (community)
- **Categories:** Business, Automation, Agents
- **Stats:** 2 total users, 1 monthly users, 50.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 company with filing histories

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Slovakia Financial Statements API & Filing Monitor

Export Slovak company financial statements, complete filing histories and
structured report tables from the official **Register účtovných závierok**
(RÚZ). Look up one IČO or 500, consume the incremental filing feed, or schedule
portfolio alerts for new statements. No login, browser, proxy, CAPTCHA, PDF
parsing, or third-party financial aggregator is required.

**Pricing:** $0.01 per delivered company, $0.001 per delivered filing change,
plus a $0.005 start charged only after RÚZ answers successfully. `NOT_FOUND`,
failed source checks, retries and quiet monitoring runs are not charged for
results.

### What it does

1. **Bulk Slovak company lookup** — resolve one or many IČOs and return stable
   company details.
2. **Historical financial statements** — fetch every linked accounting
   statement and, when requested, its structured financial reports.
3. **Incremental monitoring** — read the official `zmenene-od` feeds or compare
   a scheduled portfolio with its last successful Apify KVS snapshot.

### Main use cases

- **Auditable Slovak financial-statement export** — retain official template,
  row and column labels instead of relying on a third party's metric mapping.
- **Accounting and credit-data pipelines** — backfill complete filing histories
  by IČO and consume stable IDs and fingerprints in downstream systems.
- **New-filing alerts** — schedule `monitor` mode for a customer, supplier or
  investment portfolio and react only to source-verified changes.
- **Global RÚZ change ingestion** — consume the official incremental entity
  feeds with explicit continuation cursors and safe replay semantics.

This Actor is intentionally different from company-directory Actors that expose
basic identity, selected five-year metrics or derived risk flags. Its product is
the official RÚZ filing structure and change history. It does not guess normalized
`revenue`, `netProfit`, credit scores or risk conclusions across incompatible
templates.

### Company lookup: financial statements by IČO

```json
{
  "mode": "company",
  "icos": ["31333532"],
  "includeFinancialReports": true,
  "includeAnnualReports": false,
  "includeRaw": false
}
```

Batch input:

```json
{
  "mode": "company",
  "icos": ["31333532", "31322832"],
  "includeFinancialReports": false
}
```

The Actor emits exactly one `company` result per valid input IČO. `NOT_FOUND`
means RÚZ answered successfully but has no active accounting unit. `FAILED`
means the source could not be verified; it must never be interpreted as absence.

Sample (shortened):

```json
{
  "recordType": "company",
  "checkStatus": "SUCCESS",
  "ico": "31333532",
  "companyName": "ESET, spol. s r.o.",
  "companyId": 154048,
  "statements": [
    {
      "statementId": 6941341,
      "periodFrom": "2025-01",
      "periodTo": "2025-12",
      "statementType": "Riadna",
      "financialReportIds": [10238175, 10238176, 10238177]
    }
  ],
  "source": "slovakia-ruz",
  "sourceId": "accountingUnit:154048",
  "schemaVersion": 1
}
```

Financial table values are expanded row-by-row using the report's official
`idSablony` template. Values remain source strings to avoid losing decimal
precision. The MVP does not guess cross-template `revenue`, `netProfit`, or
other metrics; users receive auditable row labels, columns, source template IDs,
and values instead.

### Incremental changes: the official RÚZ filing feed

```json
{
  "mode": "changes",
  "changedSince": "2026-08-27T00:00:00Z",
  "entityTypes": ["accountingStatements", "financialReports"],
  "maxResults": 10000
}
```

RÚZ's feed is inclusive and returns entity IDs that were *changed*. A stateless
run cannot reliably tell whether a live ID was created or updated, so events are
named `ACCOUNTING_STATEMENT_CHANGED`, `FINANCIAL_REPORT_CHANGED`, etc. Deleted
details are explicit and become `*_DELETED`, never source failures. This avoids
manufacturing an inaccurate `ADDED`/`UPDATED` distinction.

`maxResults` is an aggregate cap across the selected feeds, consumed in the order
the feeds are listed - a busy first feed can use the whole budget and leave the
next one unscanned, which is reported as `returnedCount: 0, complete: false`
rather than as "no changes". `RUN_SUMMARY.changeFeeds` reports `returnedCount`,
`complete`, and `nextCursor` for every requested entity type. If a feed is
incomplete, continue it explicitly and preferably select only that feed:

```json
{
  "mode": "changes",
  "changedSince": "2026-08-27T00:00:00Z",
  "entityTypes": ["financialReports"],
  "continuationCursors": {"financialReports": 42000},
  "maxResults": 10000
}
```

Records are written as they complete, so dataset order is not strictly ascending
by entity ID. Sort the rows yourself if you need that; the resume contract is
`nextCursor`, which is computed from feed position and is unaffected.

If Apify's maximum-charge limit stops a run, `complete` stays `false` and
`nextCursor` advances only through the contiguous prefix that was actually
written. Concurrent records written beyond that safe cursor can therefore be
replayed, but no change ID is silently skipped.

### Portfolio monitor: new-filing alerts

```json
{
  "mode": "monitor",
  "icos": ["31333532", "31322832"],
  "stateKey": "my-slovak-portfolio",
  "includeFinancialReports": true
}
```

The first successful run writes a baseline and emits no events. Later successful
runs emit `ACCOUNTING_STATEMENT_ADDED`/`UPDATED`,
`FINANCIAL_REPORT_ADDED`/`UPDATED`, annual-report events, and `ENTITY_DELETED`
after an explicit deleted detail is confirmed. State lives in the named Apify KVS
`slovakia-ruz-monitor-state`, partitioned by `stateKey` and IČO. A failed or
partially published check never overwrites the last known-good snapshot, so event
delivery is at-least-once. Changing entity-inclusion options for an existing
`stateKey` safely replaces its baseline without emitting historical events. The KVS
stores only the configuration signature, stable IDs, fingerprints and compact
timestamps, not financial tables, raw payloads or templates.

### Output: dataset and run summary

The Actor Output Schema exposes two stable links to API and AI-agent clients:

- `results` — the default Dataset with company or change records;
- `runSummary` — the default KVS `RUN_SUMMARY` record, including continuation
  metadata for change feeds.

Both links are declared in the Actor Output Schema. `RUN_SUMMARY` also has an
explicit key-value-store JSON contract, so API clients can discover and validate
its operational fields before consuming them.

### Source freshness and limitations

- RÚZ documents API data as available at the same time as its public UI and may
  update throughout the day.
- `changedSince` is inclusive. Keep the Actor's stable `sourceId`/`fingerprint`
  when deduplicating overlapping windows.
- Relationship changes do not update parent timestamps. Select every entity
  type relevant to your incremental pipeline.
- Some records are legally non-public. `dataAccessibility` is preserved and the
  Actor does not fetch private/non-public attachments.
- Attachments and generated PDFs are not downloaded; structured JSON is the
  product.
- Monitor mode does not infer deletion merely because a child vanished from a
  parent list. It checks the missing entity detail and emits `ENTITY_DELETED`
  only for an explicit RÚZ deleted status; ambiguous 404s and active details retain
  the last successful fingerprint.

### Reliability and economics

Requests retry only timeouts and connection resets, HTTP 408, 425 and 429, and
selected 5xx responses, with a bounded exponential backoff. Every other 4xx,
including 400 and a normal 404, is answered immediately rather than retried. Independent
companies and change IDs are isolated; if more than half of logical items fail,
the Actor fails the run after preserving successful dataset rows.

After 10 consecutive source-level failures, a run opens its RÚZ circuit breaker.
Remaining items are reported or counted as `FAILED` without starting more source
requests; monitor snapshots and change continuation cursors stay at their last
verified positions. Any successful source answer before that threshold resets the
failure streak.

In company and monitor modes every remaining IČO still produces its own `FAILED`
row or outcome, so a batch of 100 inputs still answers for 100 inputs. In changes
mode the feed can hold far more IDs than a run could ever write rows for, so only
the batch already in flight is written out as `FAILED`; the IDs behind it are
simply not consumed. There the resume contract is `RUN_SUMMARY.changeFeeds`, not
the row set: `nextCursor` stays behind every ID that was not verified, so rerunning
from it replays them rather than skipping them.

`RUN_SUMMARY` reports input/result/change counts, invalid IČOs, not-found and source-failure
counts, requests, retries, 429s, duration, downloaded bytes, and requests per
result. If a monitored IČO with a prior healthy baseline suddenly returns no
active accounting unit, the Actor retains the baseline and surfaces a
`monitor_suspicious_drop` warning in metrics, logs, and run status. The verified
implementation uses zero proxy bytes and zero browser time.

Measured on 2026-08-29 using ordinary direct egress, no proxy, no browser and no
retries:

| Workload | Results | Requests | Downloaded | Duration |
| --- | ---: | ---: | ---: | ---: |
| Company batch, statements but no report bodies | 100 companies | 948 | 277,974 B | 23.6 s |
| ESET: 28 statements, 70 financial reports, 18 annual reports | 1 company | 121 | 154,503 B | 10.8 s |
| 50 records from each of all four change feeds | 164 events | 355 | 303,030 B | 31.9 s |

The 100-company batch averaged 9.48 requests, 2.78 KB downloaded and 0.24 seconds
per company at concurrency 3, producing 4.1 KB of output per company and 16.4 KB
for the largest. Change events cost 2.17 requests and 1.85 KB each, including the
lineage lookups that resolve a changed entity back to its IČO. Scaling the same
shape to 1,000 companies projects roughly 9,500 requests, 2.8 MB and four minutes;
that size has not been run against the live source, so treat it as an estimate.

Request count per company is driven by filing depth, not by company size:
requesting structured report bodies for a company with 28 statements and 70
reports cost 121 requests, an order of magnitude above the batch average. That
company serialized to 337 KB of output, or 803 KB with `includeRaw` enabled.
Budget by filings, not by IČO count.

`includeRaw` is a debugging aid, not a data feature. It attaches the official
template to every report that uses it, so the same template is repeated once per
report: 376 KB of that 803 KB example is duplicated template JSON. Leave it off
unless you are reconciling a specific record against the source.

This Actor is priced per delivered result, not per request, page or attempt. What
you pay for:

| Event | Price | Charged |
| --- | ---: | --- |
| `company-result` | **$0.01** | one company successfully written to the dataset |
| `change-event` | **$0.001** | one change-feed or monitor event successfully written to the dataset |
| `actor-start` | **$0.005** | once per run, after the source is verified |

Everything the Actor could not verify is free. A `FAILED` row costs no result
event, and neither do retries, so a bad day at RÚZ never inflates your bill. A
`NOT_FOUND` row is a verified answer and also carries no result event - you are
not charged for learning that a company has no active accounting unit. Invalid
input is rejected before a single source request is made. A first monitor
baseline emits no events, and a monitoring run that finds nothing new charges no
events either.

When a run reaches the maximum-charge limit you set, no new source lookup starts
for that mode, an in-flight paid write that is refused is not counted as
delivered, and monitor state is not advanced - so the limit costs you nothing
beyond what was actually delivered.

Cost per company is driven by filing depth, not by company count: see the
measurements above before budgeting a large batch with `includeFinancialReports`
enabled.

### API usage: run it from your own code

Run the Actor from your own code with the Apify API or Python client. Replace
`automa-flow` if the Actor is published under another account.

```bash
curl -X POST "https://api.apify.com/v2/acts/automa-flow~slovakia-financial-statements-api-filing-monitor/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
        "mode": "company",
        "icos": ["31333532"],
        "includeFinancialReports": true
      }'
```

```python
import os

from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("automa-flow/slovakia-financial-statements-api-filing-monitor").call(
    run_input={
        "mode": "company",
        "icos": ["31333532"],
        "includeFinancialReports": True,
    }
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item["checkStatus"] == "SUCCESS":
        print(item["ico"], item["companyName"], len(item["statements"]))
```

Always branch on `checkStatus`: `NOT_FOUND` is a verified empty lookup, while
`FAILED` means RÚZ could not be verified. Keep API tokens in environment
variables or Apify secrets, never in Actor input or source code.

### Scheduling and webhooks: a daily filing monitor

For a daily filing monitor, create a schedule in Apify Console or use the Python
client. Use the Actor's internal ID from its Settings page as `ACTOR_ID`:

```python
import os

from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
client.schedules().create(
    name="daily-slovak-filing-monitor",
    cron_expression="0 6 * * *",
    timezone="Europe/Bratislava",
    is_enabled=True,
    is_exclusive=True,
    actions=[
        {
            "type": "RUN_ACTOR",
            "actorId": os.environ["ACTOR_ID"],
            "input": {
                "mode": "monitor",
                "icos": ["31333532", "31322832"],
                "stateKey": "daily-supplier-portfolio",
                "includeFinancialReports": True,
            },
        }
    ],
)
```

Attach a persistent webhook to notify your endpoint after successful runs:

```python
import os

from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
client.webhooks().create(
    actor_id=os.environ["ACTOR_ID"],
    event_types=["ACTOR.RUN.SUCCEEDED"],
    request_url="https://example.com/hooks/slovak-filings",
    payload_template='{"runId":"{{resource.id}}",'
    '"datasetId":"{{resource.defaultDatasetId}}",'
    '"keyValueStoreId":"{{resource.defaultKeyValueStoreId}}"}',
)
```

The receiver should use the dataset and `RUN_SUMMARY` links to decide whether a
run contains new events. Secure the receiving URL and make processing idempotent.

### Use with AI agents through Apify MCP

Expose the Actor as a typed MCP tool with the official input and output schemas:

```text
https://mcp.apify.com?tools=automa-flow/slovakia-financial-statements-api-filing-monitor
```

Example prompt:

```text
Run automa-flow/slovakia-financial-statements-api-filing-monitor for these Slovak
IČO company IDs. Return filing history and structured financial statement rows,
separate NOT_FOUND from FAILED checks, and cite each source_url.
```

For recurring work, use `mode: monitor` and a stable `stateKey`; consume only
explicit filing events after the quiet first-run baseline.

### Legal and data use

The current official RÚZ Open API documentation states that its Open API data is
published under CC0. This Actor consumes only public API responses, does not
bypass access controls, and minimizes output to product-relevant fields unless
`includeRaw` is explicitly enabled. Users remain responsible for their lawful
use of company and any personal data.

Source: [official RÚZ Open API documentation](https://www.registeruz.sk/cruz-public/home/api).

# Actor input Schema

## `mode` (type: `string`):

company returns full company histories; changes reads the official incremental feed; monitor compares a portfolio with its last successful snapshot. Fields that belong to another mode are rejected instead of silently ignored.

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

One to 500 unique 8-digit Slovak IČOs with a valid checksum, for example 31333532. Required in company and monitor modes. An invalid row is returned as a non-billable FAILED result while the remaining IČOs continue. Must be empty in changes mode, where the official feed is global.

## `stateKey` (type: `string`):

Required in monitor mode, rejected elsewhere. Separates independent portfolio baselines in a named Apify key-value store.

## `includeFinancialReports` (type: `boolean`):

Fetch and map report table values using official template metadata. Read in company and monitor modes; reported in RUN\_SUMMARY.ignoredInputFields when set in changes mode.

## `includeAnnualReports` (type: `boolean`):

Include public annual-report metadata and attachment descriptors. Files are not downloaded. Read in company and monitor modes.

## `changedSince` (type: `string`):

Inclusive lower bound. A plain date such as 2026-08-27 is read as that day's UTC midnight; a full ISO-8601 timestamp must carry a timezone. Required in changes mode, rejected elsewhere.

## `entityTypes` (type: `array`):

Official entity feeds to read. Defaults to accounting statements and financial reports when left empty.

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

Aggregate cap across all selected entity feeds. Defaults to 10000 when left empty.

## `continuationCursors` (type: `object`):

Optional cursors returned in RUN\_SUMMARY.changeFeeds. Map a selected entity type to its nextCursor to continue an incomplete feed without replaying earlier IDs.

## `includeRaw` (type: `boolean`):

Adds official raw JSON to records. This increases dataset size and is usually unnecessary.

## Actor input object example

```json
{
  "mode": "company",
  "icos": [
    "31333532",
    "31322832"
  ],
  "includeFinancialReports": true,
  "includeAnnualReports": false,
  "continuationCursors": {},
  "includeRaw": false
}
```

# Actor output Schema

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

The default dataset: normalized company results, incremental change records, or portfolio-monitor events depending on mode.

## `runSummary` (type: `string`):

The RUN\_SUMMARY key-value record with outcomes, request/cost counters, and per-feed completion metadata for changes mode.

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

// Run the Actor and wait for it to finish
const run = await client.actor("automa-flow/slovakia-financial-statements-api-filing-monitor").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 = { "icos": ["31333532"] }

# Run the Actor and wait for it to finish
run = client.actor("automa-flow/slovakia-financial-statements-api-filing-monitor").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 '{
  "icos": [
    "31333532"
  ]
}' |
apify call automa-flow/slovakia-financial-statements-api-filing-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automa-flow/slovakia-financial-statements-api-filing-monitor"
        }
    }
}

```

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/g3XHPNRk3UImDtExP/builds/aitzUmvsz45dBELxW/openapi.json
