Post

Publiczne API do CRU (Centralny Rejestr Umów) - jak pobrać dane automatycznie?

Od 1 lipca 2026 r. działa Centralny Rejestr Umów (CRU). Sprawdziłem, jak wygląda publiczne API do CRU na rejestrumow.gov.pl - jest dostępny endpoint JSON, z którego można pobrać dane bez logowania. Pokazuję gotowe przykłady w curl oraz drugie, oficjalne API Ministerstwa Finansów z autoryzacją X-API-KEY.

Publiczne API do CRU (Centralny Rejestr Umów) - jak pobrać dane automatycznie?

Od 1 lipca 2026 r. tysiące urzędów mają obowiązek publikować swoje umowy w Centralnym Rejestrze Umów. Sieć Obywatelska Watchdog Polska od miesięcy apeluje o to, żeby dane były dostępne przez publiczne API, a nie tylko do ręcznego przeglądania po jednej umowie. I słusznie - z klikania po pojedynczych rekordach nikt nie zrobi żadnej analizy.

Postanowiłem sprawdzić, jak to naprawdę wygląda pod maską. Okazało się, że publiczne API do CRU już istnieje - tylko nikt o nim głośno nie mówi. Poniżej pokazuję, jak z niego skorzystać, oraz jak wygląda drugie, oficjalne API Ministerstwa Finansów.

Co to jest CRU i dlaczego nagle wszyscy o nim mówią

W dużym skrócie: od 1 lipca 2026 r. do rejestru trafiają wszystkie umowy zawierane przez jednostki sektora finansów publicznych. Kilka faktów, które warto znać:

  • Obowiązek dotyczy ponad 65 tysięcy jednostek - od ministerstw, przez samorządy, po szkoły i szpitale.
  • Nie ma progu kwotowego. Do rejestru idzie zarówno umowa za milion, jak i za kilkaset złotych (o ile ma formę pisemną, elektroniczną lub dokumentową - zakupy „w sklepie” na słowo są wyłączone).
  • Umowę trzeba opublikować w ciągu 30 dni od jej zawarcia lub od zmiany danych.
  • Publiczne przeglądanie działa pod adresem rejestrumow.gov.pl - na razie pojawiają się w nim tylko umowy zawarte od 1 lipca.

To potencjalnie ogromna baza danych o wydatkach publicznych. Pytanie tylko, jak się do niej dostać w sposób, który pozwoli cokolwiek policzyć.

Dlaczego samo przeglądanie to za mało

Sieć Obywatelska Watchdog Polska i Instytut Finansów Publicznych zwracają uwagę na rzecz oczywistą: rejestr, w którym można tylko ręcznie wyszukać pojedynczą umowę, nie pozwala porównać instytucji ani prześledzić wydatków w czasie. Żeby obywatelska kontrola miała sens, dane muszą być:

  • dostępne masowo (hurtowo, a nie po jednym rekordzie),
  • w otwartych formatach do maszynowego przetwarzania (CSV, JSON, XML),
  • z pełną historią zmian każdej umowy.

Pod petycją #TAKdlaCRU podpisało się ponad 1250 osób. Postulat jest prosty: dajcie publiczne API.

I tu zaczyna się ciekawa część.

Publiczne API do CRU już działa (choć nieoficjalnie)

Strona rejestrumow.gov.pl to aplikacja napisana w Angular. A takie aplikacje nie mają danych „w sobie” - pobierają je z jakiegoś API w tle. Wystarczyło otworzyć narzędzia deweloperskie w przeglądarce (klawisz F12, zakładka Network), żeby zobaczyć, skąd strona bierze umowy.

Odpowiedź: z endpointu JSON pod adresem rejestrumow.gov.pl/api-dp/v1/.... Nie wymaga on żadnego logowania ani klucza. Można z niego korzystać zwykłym curl-em z terminala albo dowolnym językiem programowania.

Jak pobrać listę umów

Najważniejsza pułapka: wyszukiwarka umów działa metodą POST, a nie GET. Jeśli spróbujesz wejść na ten adres zwykłym GET-em, dostaniesz błąd 401. Trzeba wysłać żądanie POST z ciałem w formacie JSON (na początek wystarczy puste {}):

1
2
3
4
curl -s -X POST \
  'https://rejestrumow.gov.pl/api-dp/v1/agreements/search?offset=0&limit=10' \
  -H 'Content-Type: application/json' \
  -d '{}'

W odpowiedzi dostajemy listę umów w JSON-ie. Każda umowa to m.in.: identyfikator (idUmowy), nazwa jednostki (nazwa), REGON, data zawarcia, wartość przedmiotu umowy i jej przedmiot. Do stronicowania służą parametry offset (od którego rekordu) i limit (ile rekordów naraz).

Jak filtrować wyniki (np. po REGON-ie)

Tu jest druga pułapka, na którą sam się na początku nabrałem. Filtry działają, ale nie można ich wysyłać jako pól najwyższego poziomu w ciele żądania. Jeśli wyślesz {"regon": "001262860"}, API zignoruje filtr i zwróci wszystkie umowy. Kryteria trzeba zagnieździć w obiekcie menuGlowne:

1
2
3
4
curl -s -X POST \
  'https://rejestrumow.gov.pl/api-dp/v1/agreements/search?offset=0&limit=10' \
  -H 'Content-Type: application/json' \
  -d '{"menuGlowne": {"regon": "001262860"}}'

Tak zbudowane żądanie zwraca już tylko umowy danej jednostki (u mnie dla REGON-u 001262860 - dwie umowy zamiast całego kompletu). To dokładnie ten sam sposób, w jaki filtruje oficjalna wyszukiwarka na stronie - wystarczyło podejrzeć jej żądanie w zakładce Network.

Filtrować można nie tylko po REGON-ie. W obiekcie menuGlowne działają też inne kryteria z wyszukiwarki - sprawdziłem je bezpośrednio na API:

  • regon - REGON strony umowy (zarówno jednostki publicznej, jak i kontrahenta),
  • nip - NIP strony umowy,
  • nazwa - nazwa strony umowy,
  • przedmiotUmowy - fraza z przedmiotu umowy (dopasowanie po fragmencie tekstu),
  • dataZmianyOd / dataZmianyDo - zakres dat.

Na przykład, żeby znaleźć umowy zawierające w przedmiocie słowo „materiały”:

1
2
3
4
curl -s -X POST \
  'https://rejestrumow.gov.pl/api-dp/v1/agreements/search?offset=0&limit=10' \
  -H 'Content-Type: application/json' \
  -d '{"menuGlowne": {"przedmiotUmowy": "materiały"}}'

Analogicznie po NIP-ie: -d '{"menuGlowne": {"nip": "8791012391"}}'. Kryteria w obrębie menuGlowne można łączyć - wystarczy podać kilka pól naraz.

Jak pobrać szczegóły jednej umowy

Mając idUmowy z listy, pełne szczegóły umowy pobieramy zwykłym GET-em:

1
2
curl -s \
  'https://rejestrumow.gov.pl/api-dp/v1/agreement/TU-WSTAW-IDUMOWY'

Tutaj dostajemy już komplet: strony umowy, okres obowiązywania, wartość, podstawę prawną ewentualnych wyłączeń jawności i tak dalej.

Jedno ważne zastrzeżenie

To nieudokumentowany endpoint. Skoro nie jest oficjalnie opisany, nikt nie obiecuje, że jutro będzie działał tak samo - Ministerstwo może w każdej chwili zmienić strukturę żądania (choćby nazwę menuGlowne) albo cały endpoint przebudować. Jeśli więc oprzesz na nim jakiś skrypt czy analizę, licz się z tym, że trzeba go będzie od czasu do czasu poprawić.

Drugie, oficjalne API - z autoryzacją X-API-KEY

Powyższe API służy do czytania danych publicznych. Ale Ministerstwo Finansów udostępniło też oficjalne, udokumentowane API integracyjne - przeznaczone dla jednostek i firm, które chcą automatycznie publikować umowy ze swoich systemów (np. z systemu obiegu dokumentów), zamiast wklepywać je ręcznie.

To zupełnie inny serwer i inne zasady:

  • Środowisko testowe: https://jsfp-cru-test.mf.gov.pl
  • Dokumentacja: https://jsfp-cru-test.mf.gov.pl/api-gw/docs/int/api.html
  • Autoryzacja: klucz przekazywany w nagłówku X-API-KEY.

Najważniejsze funkcje tego API to: publikacja i aktualizacja umów, wycofywanie umów z publikacji, pobieranie szczegółów umowy oraz listy streszczeń i statusów wgranych dokumentów. Lista streszczeń (/v1/api/publish/summary) pozwala już filtrować po numerze umowy, przedmiocie i zakresie dat.

Żeby dostać klucz do środowiska testowego, trzeba napisać do Ministerstwa i podać REGON, nazwę integrowanego systemu oraz szacowaną liczbę użytkowników:

  • integratorzy zewnętrzni → pomoc.cru@mf.gov.pl
  • jednostki sektora finansów publicznych → wsparcie.cru.jsfp@mf.gov.pl

Które API wybrać

Zasada jest prosta:

  • Chcesz tylko czytać i analizować publiczne dane o umowach? Użyj pierwszego API (rejestrumow.gov.pl/api-dp/v1). Nie potrzebujesz żadnego klucza, działa od ręki - pamiętaj tylko o metodzie POST przy wyszukiwaniu i o tym, że filtry trzeba zagnieżdżać w obiekcie menuGlowne.
  • Chcesz automatycznie wysyłać umowy swojej jednostki do rejestru? Załatw klucz X-API-KEY i korzystaj z oficjalnego API integracyjnego.

Moje trzy grosze jako IOD

Cieszy mnie, że publiczny endpoint w ogóle jest - to znaczy, że dane da się pobrać maszynowo, a nie tylko przeklikać. To dokładnie ta „obywatelska kontrola”, o którą upomina się Watchdog. Podobnie zresztą zautomatyzowałem sobie kiedyś monitoring decyzji UODO - dane publiczne najbardziej cieszą wtedy, gdy można je pobrać jednym poleceniem.

Mam jednak dwa zastrzeżenia. Po pierwsze - to nieoficjalny, nieudokumentowany endpoint. Skoro nie jest opisany, nikt nie obiecuje, że jutro będzie działał tak samo. Dopóki Ministerstwo nie opublikuje oficjalnego, stabilnego, publicznego API z otwartymi danymi (najlepiej wpiętego w dane.gov.pl), postulat Sieci Obywatelskiej pozostaje aktualny.

Po drugie - pamiętajmy, że w rejestrze lądują też dane osobowe (np. imiona i nazwiska osób fizycznych będących stronami umów). Jawność finansów publicznych i RODO nie są ze sobą sprzeczne, ale masowe pobieranie takich danych to już przetwarzanie, które trzeba robić z głową i w konkretnym, uzasadnionym celu. O tym jednak napiszę osobno.

Najczęściej zadawane pytania

Czy do Centralnego Rejestru Umów (CRU) istnieje publiczne API?
Tak, choć nieoficjalnie i bez dokumentacji. Strona rejestrumow.gov.pl korzysta z endpointu JSON pod adresem rejestrumow.gov.pl/api-dp/v1, który nie wymaga logowania ani klucza API i można go odpytywać zwykłym curl-em lub dowolnym językiem programowania.
Jak wyszukać umowy w API CRU po REGON lub NIP?
Trzeba wysłać żądanie POST na adres rejestrumow.gov.pl/api-dp/v1/agreements/search z kryteriami zagnieżdżonymi w obiekcie menuGlowne, np. {"menuGlowne": {"regon": "001262860"}} lub {"menuGlowne": {"nip": "8791012391"}}. Umieszczenie filtrów jako pól najwyższego poziomu żądania nie działa - API wtedy je ignoruje.
Czym różni się publiczny endpoint CRU od oficjalnego API Ministerstwa Finansów?
Publiczny endpoint (rejestrumow.gov.pl/api-dp/v1) służy wyłącznie do odczytu danych i nie wymaga autoryzacji, ale jest nieoficjalny i nieudokumentowany. Oficjalne API integracyjne Ministerstwa Finansów (środowisko testowe na jsfp-cru-test.mf.gov.pl) wymaga klucza w nagłówku X-API-KEY i służy jednostkom oraz firmom do automatycznej publikacji umów w rejestrze ze swoich systemów.

A jeśli sam bawisz się API do CRU i zauważysz, że coś działa inaczej niż opisałem - daj znać, zaktualizuję wpis.

Ten post jest dostępny na licencji CC BY 4.0 .