Mentoring Tomorrow's AI Developers

Automatic Company Data Retrieval by Tax ID – Integration with Polish Registries


Filling out order forms is one of the most frustrating aspects of online shopping. Customers must manually enter company details: name, address, postal code, city. If there’s an error – the invoice may be incorrect. Can this be simplified?

It turns out, yes. Polish public registries provide APIs that allow automatic retrieval of company data based on the tax identification number (NIP). In this article, I’ll describe how it works and what challenges you might encounter.

Why You Cannot Query KRS by NIP Directly

Many developers are surprised that it is not possible to search the official KRS API directly by NIP, even though the web-based KRS search form clearly allows this in the browser. In practice, the public API only exposes endpoints based on KRS number, so NIP-based lookup has to be implemented indirectly via other registries or commercial services.

In fact, there are several third‑party websites that sell access to their own APIs with NIP search support, usually priced per 1,000 requests, effectively reselling aggregated public data behind a paid interface. No clear public explanation is given why such functionality is not offered for free in the official API, but with the help of modern AI tools it is relatively easy to design and generate the code for a free, NIP‑driven integration that combines CEIDG, REGON and KRS.

The Problem: Three Different Registries for Different Company Types

Polish legal reality divides companies into several categories, and each is registered in a different database:

  • CEIDG (Central Registration and Information on Business Activity) – sole proprietorships
  • KRS (National Court Register) – commercial law companies (LLCs, joint-stock companies, etc.)
  • REGON (National Business Registry) – all economic entities

The key problem: you cannot determine which registry a company is in based solely on the NIP number. NIP is just a tax identifier – it says nothing about the legal form of the business.

Strategy: Cascading Registry Queries

To retrieve complete company data, you must apply a “waterfall” strategy:

1. CEIDG First – Fastest and Simplest

CEIDG is the starting point because:

  • It has the fastest API (REST, JSON)
  • Doesn’t require complicated authorization
  • Contains ~2.5 million sole proprietorships

CEIDG API v3:

If the company is in CEIDG – you have everything: name, NIP, REGON, business address. Done.

2. If Not in CEIDG – Check REGON

Absence from CEIDG likely means a corporate entity. Here, REGON (GUS API) comes to the rescue:

REGON API (BIR1):

REGON allows you to:

  • Search for a company by NIP
  • Retrieve basic data (name, REGON, entity type)
  • Most importantly: obtain the KRS number (if the company has one)

Problem: REGON doesn’t contain the current registered address. That’s why another step is needed.

3. With KRS Number – Retrieve Full Data from KRS API

Having the KRS number, you can retrieve complete data from the court register:

KRS API:

  • Endpoint: https://api-krs.ms.gov.pl/api/krs/OdpisAktualny/{KRS}
  • Format: JSON
  • Authorization: none (public API)
  • Limit: 20 queries/minute

KRS returns complete data:

  • Full company name
  • Current registered address
  • Management board information
  • Share capital
  • Company status

NIP Validation – Don’t Trust User Input

Before querying any API, validate the NIP on the application side:

NIP Format:

  • 10 digits
  • Optional “PL” prefix (for EU VAT)
  • Checksum (algorithm with weights: 6,5,7,2,3,4,5,6,7)

Checksum validation saves unnecessary API calls and protects against transcription errors.

Rate Limiting – Don’t Block Your Access

Each API has limits:

  • CEIDG: no official limit, but 10-20 req/min recommended
  • REGON: ~10 queries/second (production key)
  • KRS: 20 queries/minute

Solution: middleware throttling on the application side. Better to limit yourself (e.g., 3 queries per 5 seconds) than get banned by the API.

Error Handling – What Can Go Wrong?

Inactive Company

CEIDG returns company status. Check if status === 'ACTIVE' before filling out the form.[dane.gov]​

Missing Address Data

Some companies in REGON don’t have a KRS number (e.g., foundations, associations). In such cases, return at least the name and NIP, and leave the address for manual completion.

API Timeout

External APIs may not respond. Set a timeout (e.g., 10-15 seconds) and display a friendly error message instead of an infinite loader.

Invalid API Key

CEIDG especially requires an active key. Log 401/403 errors and monitor whether the key has expired.

Caching – Don’t Query Every Time

Company data changes rarely. Consider:

  • Caching responses for 24h-7 days
  • Storing in Redis/Memcached
  • Cache key: company_data:{nip}

You save API queries and improve UX.

User Experience

From the user’s perspective, the process should look like this:

  1. Enter NIP in form field
  2. Click “Auto-fill”
  3. After 1-2 seconds, form fills with data
  4. Can edit data if something is incorrect

Important: always allow editing of retrieved data. The API may return outdated information or the user may want to use a different address (e.g., correspondence address).

Summary

Integration with Polish registries involves:

  • 3 different APIs (CEIDG, REGON, KRS)
  • Cascading strategy (CEIDG → REGON → KRS)
  • NIP validation on client and server side
  • Rate limiting (3-10 req/min)
  • Error handling and timeouts
  • Caching for 24h-7 days

The result? Instead of transcribing 5 form fields, the user only enters the NIP and clicks one button. Fewer errors, faster orders, better UX.

Is it worth it? Absolutely. Implementation takes 1-2 days, and every B2B customer placing an order benefits from it.


CEIDG API (Central Registration and Information on Business Activity)

Official documentation:

REGON API (GUS BIR1)

Official documentation:

  • Main portal: https://api.stat.gov.pl/Home/RegonApi
  • Technical documentation: Available via GUS portal
  • SOAP endpoint: https://wyszukiwarkaregon.stat.gov.pl/wsBIR/UslugaBIRzewnPubl.svc
  • Test key: abcde12345abcde12345

PHP Library (used in project):

KRS API (National Court Register)

Official documentation:

Additional Resources

NIP Validation:

Online search engines (for testing):

Rate Limiting and Limits

  • CEIDG: No official limit, max 20 req/min recommended
  • REGON: ~10 queries/second (production key), 1 query/second (test key)
  • KRS: 20 queries/minute (official limit)

Note: This article is based on a real implementation in an e-commerce system handling thousands of B2B orders monthly.