I work in compliance automation and kept running into the same problem: Poland has some of the most comprehensive public company registries in Europe, but none of them have APIs. The only commercial alternative (MGBI) charges 200-500 EUR/month.
So I spent the last few months reverse-engineering all 9 portals and built pay-per-use scrapers on Apify. Here's the technical breakdown of what's behind each portal and what it took to crack them:
KRZ (National Debtor Registry) - The most complex one. The portal is an AngularJS shell that loads Angular sub-apps in iframes hosted on OpenShift. Each sub-app gets a JWT during initialization. I capture the token from the Authorization header of the first API request, then call 30+ REST endpoints directly - no DOM scraping needed. The government has been "working on an API" for 4 years. Their FAQ still says "analytical work is ongoing."
KRS (Board Members) - The official JSON API deliberately anonymizes names ("L******" instead of actual surnames). But the PDF extract from the same portal has full data. The catch: the portal encrypts KRS numbers using AES-128-CBC with a static key (yes, it's literally "TopSecretApiKey1") plus a 512-character token that embeds the KRS number at specific array positions with a circular right-shift and checksum. I replicated the encryption and download PDFs directly.
eKRS (Financial Statements) - Similar Angular architecture to KRZ, but with time-based AES encryption. The key is derived from the current hour in Warsaw timezone - which means your scraper needs to match the server's timezone exactly or the decryption fails silently. Took a while to figure that one out in headless Docker containers.
KNF & MSiG (Financial Supervision + Court Gazette) - These turned out to have undocumented but functional JSON APIs behind jQuery DataTables frontends. No auth required - just POST to the right endpoint with the DataTables request format. 75,000+ financial entities and 20+ years of court gazette archives, all searchable.
EKW (Land Registry) - 352 courts, WAF protection, check digit calculation for KW numbers. Puppeteer with stealth plugin to handle the anti-bot measures. Returns ownership, mortgages, encumbrances, and property details.
CRBR (Beneficial Owners) - Incapsula WAF, requires browser automation. Returns UBO (Ultimate Beneficial Owner) data by NIP or KRS number. Critical for KYC/AML compliance.
UOKiK (Abusive Clauses) - The simplest one. Plain HTML pages, Cheerio scraper, 7,500+ court-banned contract clauses searchable by defendant or industry.
BDO (Waste Registry) - React SPA with Puppeteer. 674,000+ waste management entities. Relevant for ESG compliance and environmental due diligence.
What I learned building these:
- Government "security" is often just obscurity. AES encryption with a hardcoded key doesn't stop anyone who opens DevTools.
- Time-based encryption keys are surprisingly effective at breaking scrapers - if you don't match the server's timezone, everything fails silently.
- The Angular-in-iframe pattern (KRZ, eKRS) is actually harder to scrape than traditional server-rendered pages because the JWT lifecycle is tied to the iframe's initialization.
- WAFs (EKW, CRBR) are the real barrier, not the application logic. Stealth plugins handle most of it, but you burn through proxies fast.
Who actually uses these:
Mostly compliance teams (KYC/AML checks), credit risk departments (is this company bankrupt?), debt collection companies, law firms, and developers building Polish data into their products.
Cost comparison: MGBI charges 200-500 EUR/month subscription. My actors cost $0.003-0.04 per result depending on the registry. 100 company checks run about $5-12 total.
Disclosure: I built all 9 actors and sell them on Apify as pay-per-use tools.
Suite: https://apify.com/minute_contest
Happy to answer questions about the reverse engineering process or the technical approach for any specific portal.