getregdata
Start free on Apify
Home / Blog / Article
Article · 2025-12-29

How to Extract Polish Company Financial Data with a Single API Call

webscraping · api · tutorial · javascript · 4 min read

Ever needed financial data on a Polish company? Whether you’re building a fintech app, doing competitor analysis, or automating due diligence, accessing data from Poland’s National Court Register (KRS) can be… painful.

In this tutorial, I’ll show you how to get balance sheets, income statements, and key financial metrics from any Polish company in under 30 seconds.

The Problem

Poland requires all companies to submit annual financial statements to the eKRS portal. This data is public, but:

  • No official API exists
  • Multiple page navigations required
  • Files come in XML or XHTML format
  • Complex Polish accounting schemas (AktywaRazem, KapitalWlasny, ZyskNetto…)
  • Different schemas for different accounting standards (UoR vs IFRS)

Building a scraper from scratch takes 20-40 hours. But that’s just step one — then you need to parse the XML, which means learning Polish accounting terminology and handling multiple schema versions.

The Solution

We’ll use the Poland KRS Financial Scraper Actor on Apify. It handles all the complexity — including XML parsing — and returns structured JSON with financial metrics ready to use.

Key benefit: You get totalAssets, equity, revenue, netProfit etc. directly in JSON — no XML parsing required on your end.

Prerequisites

  • Free Apify account (sign up here)
  • API token (found in Apify Console → Settings → Integrations)
  • A Polish company’s NIP (tax ID) or KRS number

Method 1: Using the Apify Console (No Code)

The simplest way to test:

  1. Go to the Actor page
  2. Enter input:
{
  "krs": "0000023302"
}
  1. Click “Start”
  2. Wait ~30 seconds
  3. View results in the “Dataset” tab

Method 2: Using the API (JavaScript/Node.js)

For integration into your applications:

const Apify = require('apify-client');

const client = new Apify.ApifyClient({
    token: 'YOUR_API_TOKEN',
});

async function getPolishCompanyFinancials(krsNumber) {
    // Start the Actor
    const run = await client.actor('minute_contest/poland-krs-financial-scraper').call({
        krs: krsNumber
    });

    // Get results from dataset
    const { items } = await client.dataset(run.defaultDatasetId).listItems();

    return items[0];
}

// Example usage
const financials = await getPolishCompanyFinancials('0000023302');
console.log(financials);

Output:

{
  "krs": "0000023302",
  "year": 2024,
  "fileName": "Sprawozdanie_finansowe_2024.xml",
  "fileFormat": "xml",
  "financials": {
    "totalAssets": 54850000000,
    "equity": 32100000000,
    "fixedAssets": 42100000000,
    "currentAssets": 12750000000,
    "revenue": 33500000000,
    "operatingProfit": 4200000000,
    "netProfit": 2850000000
  },
  "success": true
}

Method 3: Using cURL

For quick command-line testing or integration with any language:

# Start the Actor and wait for results
curl -X POST "https://api.apify.com/v2/acts/minute_contest~poland-krs-financial-scraper/run-sync-get-dataset-items" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -d '{"krs": "0000023302"}'

Method 4: Using Python

from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

def get_polish_company_financials(krs_number):
    run_input = {"krs": krs_number}

    run = client.actor("minute_contest/poland-krs-financial-scraper").call(run_input=run_input)

    items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
    return items[0] if items else None

# Example
financials = get_polish_company_financials("0000023302")
print(f"Total Assets: {financials['financials']['totalAssets']:,} PLN")
print(f"Net Profit: {financials['financials']['netProfit']:,} PLN")

Using NIP Instead of KRS

Don’t have the KRS number? Use the company’s NIP (tax ID) instead:

const financials = await getPolishCompanyFinancials({ nip: '8992736629' });

The Actor will automatically look up the KRS number from the NIP.

Understanding the Output

Parsed Financial Metrics

FieldPolish NameDescription
totalAssetsAktywa razemTotal assets
fixedAssetsAktywa trwałeFixed/non-current assets
currentAssetsAktywa obrotoweCurrent assets
equityKapitał własnyShareholders’ equity
revenuePrzychodyRevenue from sales
operatingProfitZysk operacyjnyOperating profit
netProfitZysk nettoNet profit

Raw Data Access

For custom parsing, the full XML/XHTML file is available in rawXml:

const { rawXml, fileFormat } = financials;

if (fileFormat === 'xml') {
    // Parse Polish Accounting Standards format
    const parser = new DOMParser();
    const doc = parser.parseFromString(rawXml, 'text/xml');
    // Custom extraction...
}

Real-World Use Cases

1. Competitor Analysis Dashboard

const competitors = ['0000023302', '0000012345', '0000067890'];

const results = await Promise.all(
    competitors.map(krs => getPolishCompanyFinancials(krs))
);

// Compare metrics
results.forEach(company => {
    console.log(`KRS ${company.krs}: Revenue ${company.financials.revenue}`);
});

2. Automated Due Diligence

async function dueDiligenceCheck(nip) {
    const financials = await getPolishCompanyFinancials({ nip });

    const checks = {
        hasPositiveEquity: financials.financials.equity > 0,
        isProfitable: financials.financials.netProfit > 0,
        currentRatio: financials.financials.currentAssets /
                      (financials.financials.totalAssets - financials.financials.equity)
    };

    return { financials, checks };
}

3. Bulk Data Collection

const companies = readCSV('polish_companies.csv'); // List of KRS numbers

for (const krs of companies) {
    const data = await getPolishCompanyFinancials(krs);
    await saveToDatabase(data);
    await sleep(1000); // Rate limiting
}

Pricing

The Actor uses pay-per-result pricing:

  • ~$0.03 per successful extraction
  • No subscription required
  • Free tier available for testing

Error Handling

const result = await getPolishCompanyFinancials('0000023302');

if (!result.success) {
    console.error(`Error: ${result.error}`);
    // Common errors:
    // - "Company not found" - Invalid KRS number
    // - "No financial statements" - Company hasn't filed yet
    // - "Multiple formats" - Handle XHTML separately
}

Conclusion

Accessing Polish company financial data doesn’t have to be complicated. With a single API call, you can get structured financial metrics ready for analysis.

Links:


Have questions? Drop them in the comments!


Turn this into working data. Browse the registries and use cases, or start free on Apify.

Originally published on Dev.to.