Polish Legal Acts API – Dziennik Ustaw & ELI avatar

Polish Legal Acts API – Dziennik Ustaw & ELI

Pricing

from $6.40 / 1,000 act with texts

Go to Apify Store
Polish Legal Acts API – Dziennik Ustaw & ELI

Polish Legal Acts API – Dziennik Ustaw & ELI

Polish legal acts (akty prawne) from the official Sejm ELI API — Dziennik Ustaw and Monitor Polski. Metadata, legal references and optional plain text. Export CSV, JSON or Excel.

Pricing

from $6.40 / 1,000 act with texts

Rating

0.0

(0)

Developer

Kamil Kaczmarek

Kamil Kaczmarek

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Poland Legal Acts API – Dziennik Ustaw & ELI

Poland legal acts API: search akty prawne from the official Sejm ELI API — Dziennik Ustaw and Monitor Polski. Export ELI identifiers, titles, dates, keywords, legal references, and optional plain text (pełny tekst aktu) from HTML or PDF for legal-tech tools, compliance monitoring, and RAG. Filter by year, dates, title, keywords, act type, or in-force status; monitor new and changed acts with persistent revision tracking. Polski opis: akty prawne z oficjalnego API ELI Sejmu (DU i MP) — metadane, powiązania i opcjonalnie tekst; eksport CSV, JSON lub Excel.

What data can you get

  • ELI identifier, publication, year, position, Polish title, act type, and source status.
  • Announcement, promulgation, change, and legal status dates, plus entry into force when available.
  • Official keywords, issuing bodies, and references grouped by reference type.
  • Links to the ELI record, ISAP page, and available HTML and PDF documents.
  • Optional plain text with its source, retained character count, truncation flag, and extraction error.

includeDetails=true is the default. It fetches the fields that the search response may omit, including keywords, references, and inForce. With details disabled, missing values remain null, empty arrays, or an empty references object. The Actor preserves source status strings such as IN_FORCE.

How to use

  1. Set publisher to DU for Dziennik Ustaw or MP for Monitor Polski.
  2. Provide at least year or dateFrom. Dates use YYYY-MM-DD.
  3. Add filters and set maxItems. Enable includeText for document text.
  4. Run the Actor and export the dataset as JSON, CSV, or Excel through Apify.

Start with this input:

{
"publisher": "DU",
"year": 2026,
"maxItems": 5,
"includeDetails": true,
"includeText": false
}

The examples include a examples/smoke.json, examples/monitor-last-week.json, examples/mp-keyword.json, and examples/du-tax-with-text.json. The weekly example covers 2026-10-12 through 2026-10-18. Update those fixed dates before using it for another week.

Input

Dziennik Ustaw 2026 tax-related acts with extracted text (capped):

{
"publisher": "DU",
"year": 2026,
"titleContains": "podatk",
"includeDetails": true,
"includeText": true,
"maxTextChars": 100000,
"maxItems": 5
}

Monitor Polski 2026 by official keyword (metadata + details):

{
"publisher": "MP",
"year": 2026,
"keywords": ["ceny"],
"includeDetails": true,
"maxItems": 20
}

Omit unused optional strings rather than sending empty strings. dateFrom must be on or before dateTo. If you supply both a year and dates, both filters apply.

FieldDefaultMeaning
publisher"DU"DU or MP.
yearOmittedPublication year, 1-9999. Required unless dateFrom is supplied. The Console form prefills 2026.
dateFromOmittedInclusive lower bound for the selected date field.
dateToOmittedInclusive upper bound for the selected date field.
dateField"promulgation"promulgation, announcement, or effect. Maps to ELI pubDate*, date*, or dateEffect*.
titleContainsOmittedWords in the Polish title. Try the stem podatk; inflection affects matches.
keywords[]Official Polish subject keywords, sent as comma-separated keyword.
actTypes[]Exact types such as Ustawa, Rozporządzenie, or Obwieszczenie. Multiple values match any selected type.
inForceOnlyfalseFilter through the API's in-force flag.
includeDetailstrueFetch individual act details. Adds one request per act.
includeTextfalseExtract plain text, preferring HTML and falling back to PDF.
maxTextChars0No user cutoff at zero. Positive values cap retained characters. Automatic safety limits always apply.
sortOrder"newest"newest sorts by descending publication position; oldest sorts ascending. Cross-year date order is not guaranteed.
maxItems100Maximum delivered dataset rows, 1-100000. Skipped revisions do not count.
onlyNewfalseSkip ELI plus changeDate revisions already delivered for this state key.
stateKey"default"Monitoring history key, 1-100 letters, digits, underscores, or hyphens.
maxRequestsPerSecond3Advanced setting, 0.2-10 requests per second across all endpoints and retries.

One act type is sent to the API as type. Multiple act types are filtered locally within one paginated search stream. Selective filters can therefore require additional search pages. maxItems limits delivered items, not requests or scanned candidates.

Monitor new and changed acts

Set onlyNew=true and keep the same stateKey across runs. The named key-value store polish-legal-acts-seen retains the latest 50,000 delivered revisions, identified by ELI plus changeDate. A changed act can appear again without a charge for skipped revisions. Different state keys maintain independent histories.

Use overlapping date ranges or a broad year filter to revisit older acts that may have changed. The date filters select announcement, promulgation, or effective dates. They do not filter on changeDate. Run schedules sharing a state key sequentially. A crash after a dataset write but before state persistence can cause a repeat, and evicted revisions can appear again.

Output

Each dataset item represents one act. This shortened example uses the recorded DU/2026/1338 fixture and omits some metadata fields:

{
"eli": "DU/2026/1338",
"publisher": "DU",
"year": 2026,
"position": 1338,
"displayAddress": "Dz.U. 2026 poz. 1338",
"title": "Rozporządzenie Prezesa Rady Ministrów z dnia 14 października 2026 r. w sprawie przedterminowych wyborów wójta gminy Sadlinki w województwie pomorskim",
"type": "Rozporządzenie",
"inForce": "IN_FORCE",
"promulgationDate": "2026-10-15",
"keywords": ["gminy", "kodeks wyborczy", "administracja samorządowa", "samorząd terytorialny", "wybory"],
"references": {
"Podstawa prawna": ["DU/2011/112"],
"Podstawa prawna z art.": ["DU/2011/112"]
},
"hasHtml": false,
"hasPdf": true,
"urlEli": "https://api.sejm.gov.pl/eli/acts/DU/2026/1338",
"urlIsap": "https://isap.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20260001338",
"urlPdf": "https://api.sejm.gov.pl/eli/acts/DU/2026/1338/text.pdf"
}

With includeText=true, delivered items also have text, textSource, textLength, textTruncated, and textError. textSource is html or pdf, and textError is null on delivered items. textLength counts the characters retained after truncation. If extraction fails for all available formats, the Actor logs the error and skips the act without a charge or a delivered-revision entry in onlyNew history. A later run can retry that revision. Skipped extraction failures do not count toward maxItems. Every item includes scrapedAt in UTC. Source dates and timestamps retain their source format.

The full field list and table view are in .actor/dataset_schema.json. Run statistics are saved to the default key-value store under RUN_STATS, including requests, retries, failed attempts, pushed items per event, skipped seen revisions, and duration.

Pricing (pay per event)

EventUSD per delivered actWhen charged
act$0.002Metadata with includeText=false.
act-with-text$0.008Nonempty text was extracted, including truncated text.

An act receives one of these charges. For example, 100 metadata acts cost $0.20 in event fees; 100 acts with extracted text cost $0.80. Search requests and skipped seen revisions do not trigger these events. The SDK enforces the run's maximum total charge and stops delivery when the remaining budget cannot cover another item. On local runs, the equivalent budget variable is ACTOR_MAX_TOTAL_CHARGE_USD.

.actor/pay_per_event.json records the two events for manual configuration in the Apify Console. The platform does not read that file automatically. Configure those prices when publishing.

Use cases

  • Legal-tech tools that index Polish legislation and cross-references.
  • Compliance monitoring for new and changed DU or MP acts within a watched scope.
  • AI agents and RAG pipelines that need plain text with traceable ELI and PDF links.
  • Research on publication patterns, act types, official keywords, and legal references.

FAQ

Is there an API for Polish legal acts / ELI / akty prawne? Yes. The Sejm publishes a public ELI API for Dziennik Ustaw and Monitor Polski. This Actor turns live akty prawne into a filterable table (year, dates, title, keywords, act type, optional text) callable from the Apify API, with CSV/JSON/Excel export.

How do I export Dziennik Ustaw or Monitor Polski to CSV or Excel? Set publisher to DU or MP, provide year or dateFrom, set maxItems, optionally includeText, run the Actor, then download the dataset as CSV or Excel from the run page or via the Apify API.

Does it include the full text of each act? Only when you set includeText: true. The Actor prefers HTML and falls back to PDF; it does not perform OCR. Metadata-only runs stay cheaper (act event).

What is the difference vs scraping ISAP HTML? This Actor uses the official Sejm ELI HTTP API (not HTML scraping of isap.sejm.gov.pl). You get structured ELI metadata, references, and optional extracted text with source links.

How fast / how many requests?

Real local apify run measurements on 2026-10-18, without login, produced the following results for 100 acts:

ModeSettingsSource requestsElapsed time
Search metadata onlyincludeDetails=false, includeText=false11.6 s
Metadata with detailsincludeDetails=true, includeText=false10135 s
Details with textincludeDetails=true, includeText=true201171 s

The text run produced a 9.1 MB dataset. Its largest item was 0.97 MB. All texts came from PDF. These measurements describe those runs, not a runtime guarantee. Source response time, PDF size and complexity, retries, filters, and hardware affect duration.

Each search page requests up to 500 source acts. Details add one request per prepared act. Text adds one request for an available HTML document or PDF, with an additional request if HTML fails and PDF fallback is needed. Seen revisions can be skipped before enrichment. Multiple-type filtering or skips can require more search pages to fill maxItems.

Why does a recent act use PDF instead of HTML?

The source checks on 2026-10-18 found no HTML text for the 2025-2026 acts examined. DU 2024 includes HTML documents. The Actor checks each act's availability flags, prefers HTML when available, and falls back to PDF. Empty HTTP 200 HTML responses and recognized error or maintenance pages also trigger PDF fallback. Error detection checks the page title and the start of visible text, so a later mention of a service error in legal text does not trigger fallback.

Can large texts exceed the dataset limit?

Apify limits each dataset item to 9 MB of serialized JSON. The 9.1 MB measurement above is the whole dataset across 100 separate items. maxTextChars=0 disables the user cutoff, but the Actor always truncates text above 8,000,000 characters. It also applies an 8,900,000-byte JSON budget, including metadata and escaping. Unicode characters can therefore trigger truncation before the character ceiling. Every truncation sets textTruncated=true.

Use a smaller maxTextChars, for example 100000, if your downstream system needs shorter documents. PDF downloads are limited to 50 MiB. If no HTML text is available, scanned PDFs without extractable text cause the act to be skipped with a logged error. The Actor does not perform OCR. PDF extraction can need more memory than metadata runs. The Actor allows up to 1024 MiB.

Data comes from the official public Sejm ELI API, with links to ISAP. No source API key is required. Polish legal acts are excluded from copyright protection under Article 4 of the Polish Copyright Act. The Actor collects published legal documents and metadata. It does not seek private personal data or build personal profiles; published documents may themselves name people.

What rate limits and failure handling apply?

The default cap is 3 requests per second, configurable up to 10, with at most two requests in flight. Requests time out after 60 seconds. The client retries transient transport failures, HTTP 429, 500, 502, 503, and 504, and invalid JSON responses. It uses backoff with jitter and honors numeric Retry-After values, capped at 60 seconds, for up to five retries.

These are Actor settings, not an official source quota. Keep the rate low when the source is under load. A details 404 retains search metadata. When all available text formats fail, the Actor logs the error and skips the act without a charge or a new delivered-revision entry. A search or details outage after retries fails the run while retaining items already saved.

How fresh and complete are the results?

The Actor reads the API during each run. Availability, publication timing, status, document coverage, and corrections depend on Sejm. changeDate is the source's revision timestamp. scrapedAt records retrieval time. A date filter only revisits acts within that date range. Source pagination is not a snapshot, so changes during a run can affect coverage. Use overlapping monitoring windows.

Integrations

Use the Apify API to start runs with the same JSON input and retrieve dataset items. Configure Apify schedules for recurring monitoring, and webhooks for completion notifications to your own systems. Connect the Actor through an Apify MCP integration or call its run and dataset APIs from AI agents. RAG pipelines can index text and retain eli, source URLs, and dates as citations. No custom webhook, MCP server, or scheduler is bundled in this repository.

Development

Use Python 3.13, Apify SDK 4.1, httpx, and pypdf. Runtime dependencies are in requirements.txt; test dependencies are in requirements-dev.txt. In this workspace the shared environment already contains them. No installation is needed.

Activate the shared environment and run locally with Apify CLI, without login:

source /workspace/samofinans/actors/.venv/bin/activate
apify run --input-file examples/smoke.json

A normal Actor run contacts the public Sejm API. The tests use recorded fixtures and block network access. Local datasets and key-value stores live under ./storage.

Simulate pay-per-event prices locally

Use all three environment variables below. APIFY_ACTOR_PRICING_INFO must contain the JSON itself. APIFY_CHARGED_ACTOR_EVENT_COUNTS must contain explicit zero counts for both events. In SDK 4.1 an empty {} is ignored, which leaves events priced at USD 1.00 as "Unknown event" in local test mode.

Delete ./storage before each simulation. This also resets local monitoring state. Default-store purge does not clear the named charging-log dataset, so purge alone leaves stale billing records.

source /workspace/samofinans/actors/.venv/bin/activate
rm -rf ./storage
export ACTOR_TEST_PAY_PER_EVENT=true
export APIFY_ACTOR_PRICING_INFO="$(cat examples/pricing_info.local.json)"
export APIFY_CHARGED_ACTOR_EVENT_COUNTS='{"act":0,"act-with-text":0}'
export ACTOR_MAX_TOTAL_CHARGE_USD=0.01
apify run --input-file examples/smoke.json

That example allows five metadata items at USD 0.002 each. Inspect the default dataset, the named charging-log dataset, and RUN_STATS. The local pricing JSON includes a zero-priced apify-default-dataset-item entry because the SDK tracks this automatic event too. The Actor never charges synthetic apify-* events manually. The two billable events remain act and act-with-text.

Clear simulation settings before an ordinary local run:

$unset ACTOR_TEST_PAY_PER_EVENT APIFY_ACTOR_PRICING_INFO APIFY_CHARGED_ACTOR_EVENT_COUNTS ACTOR_MAX_TOTAL_CHARGE_USD

Run offline checks

/workspace/samofinans/actors/.venv/bin/python -m pytest -q
/workspace/samofinans/actors/.venv/bin/python -m compileall src
apify validate-schema

The offline suite covers input validation, query construction, pagination, HTML and PDF extraction, empty HTML fallback, size limits, retries, billing, charge limits, and seen revisions. Fixtures in tests/fixtures were recorded on 2026-10-18.

Disclaimer

This is an unofficial Actor. It is not affiliated with or endorsed by Sejm or the publishers. Output reflects the source responses and extraction limits. Check the linked official documents when you need the authoritative text.

🇵🇱 Po polsku

Actor pobiera akty prawne z Dziennika Ustaw i Monitora Polskiego przez oficjalne API ELI Sejmu. Zwraca metadane, słowa kluczowe, powiązania prawne i adresy dokumentów. Opcjonalnie wyodrębnia tekst z HTML lub PDF. Nie wykonuje OCR.

W polu publisher wybierz DU albo MP. Podaj co najmniej year lub dateFrom. Zakres dat dotyczy daty wskazanej w dateField. Szukając przepisów podatkowych, użyj titleContains="podatk", ponieważ odmiana polskich słów wpływa na wyniki. includeDetails=true dodaje szczegóły, a includeText=true włącza tekst.

Wynik zawiera jeden akt w każdym rekordzie, z identyfikatorem eli, tytułem, datami i adresami źródłowymi. textLength oznacza długość zachowanego tekstu. maxTextChars=0 wyłącza limit użytkownika, ale nadal obowiązuje limit 8 mln znaków i limit rozmiaru JSON poniżej 9 MB. Pole textTruncated informuje o skróceniu tekstu.

ZdarzenieCena za zapisany aktZakres
act0,002 USDMetadane przy includeText=false.
act-with-text0,008 USDAkt z wyodrębnionym tekstem, również skróconym.

Ustaw onlyNew=true i zachowaj ten sam stateKey, aby monitorować nowe i zmienione akty. Historia obejmuje do 50 tys. rewizji ELI plus changeDate. Pominięte rewizje nie są płatne. Gdy przy includeText=true nie uda się uzyskać tekstu z żadnego dostępnego formatu, akt jest pomijany bez opłaty i bez dodania rewizji do historii. Kolejne uruchomienie może ponowić próbę. Stosuj nakładające się zakresy dat i uruchomienia sekwencyjne dla jednego klucza. Przykładowy zakres tygodniowy ma stałe daty, które trzeba aktualizować.