# EU Law Lookup API (EUR-Lex): article text, in force, amendments (`bosco_labs/eu-law-lookup`) Actor

The text of an EU law article as in force today (or on a date), whether the act is in force, what amended it, plus new Official Journal acts. Ask by name (GDPR, AI Act), citation, CELEX or ELI; 24 languages. Official EUR-Lex/Cellar data with a source link per row.

- **URL**: https://apify.com/bosco_labs/eu-law-lookup.md
- **Developed by:** [Bosco Labs](https://apify.com/bosco_labs) (community)
- **Categories:** Business, AI, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 act or articles

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## EU Law Lookup API (EUR-Lex): article text, in force, amendments

**One call answers "what does Article 50 of the AI Act say today, is it in force, and what
amended it?"**: the article as plain text from the current consolidated version (or the one in
force on any date), the act's in-force status and dates, and the acts that amend, correct or
repeal it. A second mode lists new acts in the Official Journal L series. Built for **AI agents**
doing legal and compliance work, and for people who want a sourced answer without SPARQL.

**Pricing (pay per event):** $0.005 per act or article returned (`act-lookup`). A citation that
can't be read, or an article that doesn't exist, fails in seconds and costs nothing.

### What you get

One JSON row per requested article (or one row for the act). Real output for
`{"query": "AI Act", "article": "50"}`, run on 2026-11-05 (article text, `corrected_by` and
`amends` shortened):

```json
{
  "schema_version": "1",
  "query": "AI Act",
  "celex": "32024R1689",
  "eli": "http://data.europa.eu/eli/reg/2024/1689/oj",
  "title": "Regulation (EU) 2024/1689 of the European Parliament and of the Council of 13 June 2024 laying down harmonised rules on artificial intelligence and amending Regulations (EC) No 300/2008, ... (Artificial Intelligence Act) (Text with EEA relevance)",
  "act_type": "Regulation",
  "act_type_code": "REG",
  "date_document": "2024-06-13",
  "date_publication": "2024-07-12",
  "oj_reference": "OJ L, 2024/1689",
  "date_entry_into_force": "2024-08-01",
  "entry_into_force_dates": ["2024-08-01", "2025-02-02", "2025-08-02", "2026-08-02", "2027-08-02"],
  "date_end_of_validity": null,
  "in_force": true,
  "eur_lex_url": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32024R1689",
  "summary_url": "https://eur-lex.europa.eu/legal-content/EN/LSU/?uri=CELEX:32024R1689",
  "language": "EN",
  "as_of": null,
  "latest_consolidated_version_date": "2026-07-27",
  "text_version": "consolidated",
  "text_celex": "02024R1689-20260727",
  "consolidated_version_date": "2026-07-27",
  "text_notice": "This text is meant purely as a documentation tool and has no legal effect. The Union's institutions do not assume any liability for its contents. The authentic versions of the relevant acts, including their preambles, are those published in the Official Journal of the European Union and available in EUR-Lex. ...",
  "source_url": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02024R1689-20260727",
  "cellar_url": "http://publications.europa.eu/resource/cellar/b1730fb2-8f1c-11f1-9262-01aa75ed71a1.0001.03/DOC_1",
  "amended_by": [
    {
      "celex": "32026R1744",
      "title": "Regulation (EU) 2026/1744 of the European Parliament and of the Council of 8 July 2026 amending Regulations (EU) 2024/1689, (EU) 2018/1139 and (EU) 2023/1230 as regards the simplification of the implementation of harmonised rules on artificial intelligence (Digital Omnibus on AI) (Text with EEA relevance)",
      "date": "2026-07-08",
      "url": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32026R1744"
    }
  ],
  "corrected_by": [
    { "celex": "32024R1689R(04)", "title": null, "date": "2026-05-04", "url": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32024R1689R(04)" }
  ],
  "repealed_by": [],
  "implicitly_repealed_by": [],
  "amends": [
    { "celex": "32020L1828", "title": "Directive (EU) 2020/1828 of the European Parliament and of the Council of 25 November 2020 on representative actions ...", "date": "2020-11-25", "url": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32020L1828" }
  ],
  "repeals": [],
  "implicitly_repeals": [],
  "article": "50",
  "paragraph": null,
  "article_title": "Transparency obligations for providers and deployers of certain AI systems",
  "article_text": "1. Providers shall ensure that AI systems intended to interact directly with natural persons are designed and developed in such a way that the natural persons concerned are informed that they are interacting with an AI system, ...\n2. Providers of AI systems, including general-purpose AI systems, generating synthetic audio, image, video or text content, shall ensure that the outputs of the AI system are marked in a machine-readable format ...\n...\n7. The Commission shall encourage and facilitate the drawing up of codes of practice at Union level ...",
  "article_text_truncated": false,
  "article_amended_by": [{ "celex": "32026R1744", "change": "replaced" }],
  "warnings": [],
  "retrieved_at": "2026-11-05T21:50:10+00:00",
  "duration_seconds": 0.7
}
```

- **article_text**: plain text, one line per paragraph or point, numbering kept (`1.`, `(a)`;
  German texts use `(1)`). Ask for a paragraph with `"article": "6(1)"`.
- **article_amended_by**: in a consolidated text, the acts that changed this very article
  (from EUR-Lex's change markers).
- **in_force**, **date_entry_into_force**, **entry_into_force_dates** (staged application
  dates), **date_end_of_validity**: as EUR-Lex records them.
- **amended_by / corrected_by / repealed_by / amends / repeals**: each with CELEX, title,
  date and EUR-Lex link, newest first.
- **source_url**: the EUR-Lex page of the exact text version used; **eli** and **eur_lex_url**
  for the act itself.
- Without `article`: one row with `table_of_contents` (every article and its heading),
  `articles_count`, `recitals_count` and `summary_url`, so an agent can pick the article for a
  second call. The whole text only with `"include": ["text"]`, cut at `maxTextChars`.

### Input

```json
{ "query": "AI Act", "article": "50", "language": "EN", "asOf": "2026-11-05" }
```

| Field | Meaning |
|---|---|
| `query` | The act: `GDPR`, `AI Act`, `DSA`, `NIS2`, `DORA`, `MiCA`, `CSRD`... (short names for 42 well-known acts), `Regulation (EU) 2024/1689`, `Directive 95/46/EC`, `Regulation (EC) No 1907/2006`, `2016/679`, CELEX `32016R0679`, ELI `http://data.europa.eu/eli/reg/2016/679/oj`, or `AI Act Article 50` |
| `article` | `5`, `6(1)`, `4a`, or several: `5, 6(1)` (max 10). Empty = act overview |
| `language` | Any of the 24 EU language codes; default `EN` |
| `asOf` | `YYYY-MM-DD`: the consolidated version that applied on that date. Default today |
| `include` | `metadata` (always), `amendments` (default), `citing` (acts and judgments citing it), `text` (whole act) |
| `maxTextChars` | Cap for article and act text, default 30000 |
| `ojSince`, `keywords`, `maxResults` | Official Journal mode, see below |

**New acts in the Official Journal:** `{"ojSince": "2026-11-03", "keywords": "data, cyber"}`
lists every act published in the OJ L series since that date (max 31 days back), newest first,
optionally only those whose title contains any keyword. One row (and one charge) per act, with
the same metadata fields. Leave `query` empty in this mode.

### Use from an AI agent (MCP)

Agents can call this Actor as a tool through the
[Apify MCP server](https://github.com/apify/apify-mcp-server). Add this server URL to your MCP
client (Claude, Cursor, VS Code, ...):

```text
https://mcp.apify.com?tools=bosco_labs/eu-law-lookup
```

It loads this Actor as a tool, plus the tools that read its results (`get-actor-run`,
`get-dataset-items`). The hosted server signs you in with OAuth, or accepts your Apify token as
`Authorization: Bearer <APIFY_TOKEN>`.

Example prompt: *"What does Article 50 of the AI Act require today, and has it been amended?
Quote the text and link the source."* The agent passes:

```json
{ "query": "AI Act", "article": "50" }
```

**Output for agents:** small JSON rows (typically 5-20 KB), stable `snake_case` fields, ISO
dates, `null` for unknown, a EUR-Lex link for the act, the text version and every related act.
`warnings` says in plain words when a fallback was used (another language, the OJ text instead
of a consolidated version) or the act was not in force on `asOf`. A lookup takes about 1 second
after start-up (measured 0.6-0.7 s for GDPR Art. 5 and AI Act Art. 50).

**Cost:** $0.005 per act or article returned, billed to the Apify account the MCP server is
signed in with. Nothing is charged for a failed lookup.

### FAQ

**Where does the data come from?** Only from the Publications Office of the EU, the publisher of
EUR-Lex: its Cellar repository (SPARQL endpoint for metadata and relations, REST content
negotiation for texts). Nothing else is added, and the text is not rewritten or summarised.

**Is the consolidated text the law?** No. Consolidated versions are, in EUR-Lex's own words, "a
documentation tool" with no legal effect; only the texts published in the Official Journal are
authentic. Every row with a consolidated text carries EUR-Lex's disclaimer in `text_notice` and
links the authentic act in `eur_lex_url`. Ask with an `asOf` before the first consolidated
version to get the OJ text itself.

**Is this legal advice?** No. It returns official texts and metadata as published; it does not
interpret them. EUR-Lex itself states its information is not professional or legal advice.

**Which acts work?** Any act with a CELEX number in EUR-Lex: regulations, directives and
decisions, corrigenda and consolidated versions. Article extraction works on
all current texts; for some old acts (before about 2000) only an HTML text without article
markup exists, and the last article may then include trailing headings. Annexes are not split
out (use `include: ["text"]`).

**How current is it?** Live: every call reads Cellar directly. New OJ acts appear the day they
are published; consolidated versions follow when the Publications Office produces them (days
to weeks), so `latest_consolidated_version_date` can lag behind `amended_by`. `in_force` can be
`null` for acts published in the last few days, before EUR-Lex has set it.

**Why is a title null?** Some corrigenda have no title in Cellar, and very new acts may not yet
have one in every language.

**Points like 6(1)(a)?** The paragraph is returned whole; points are lines inside it.

**Personal data?** None is requested or returned beyond what the published legal acts contain.
Signatory names in the metadata are not output.

Content: © European Union, https://eur-lex.europa.eu (reuse under Commission Decision
2011/833/EU; consolidated texts and editorial content under CC BY 4.0; metadata CC0). Text is
converted from XHTML to plain text and long texts are cut where `maxTextChars` says; nothing
else is changed.

# Actor input Schema

## `query` (type: `string`):

The EU act to look up: a short name ("GDPR", "AI Act", "DSA", "NIS2", "DORA", "MiCA", "CSRD"...), a citation ("Regulation (EU) 2024/1689", "Directive 95/46/EC", "Regulation (EC) No 1907/2006"), a bare number ("2016/679"), a CELEX number ("32016R0679") or an ELI URI ("http://data.europa.eu/eli/reg/2016/679/oj"). "AI Act Article 50" also works. Leave empty only when using ojSince (new Official Journal acts). An unreadable citation fails in seconds, with examples, at no charge.

## `article` (type: `string`):

Article number, optionally with a paragraph: "5", "6(1)", "4a"; several separated by commas ("5, 6(1)", up to 10). One row per article. Empty = one row for the whole act with its table of contents and recital count (no full text unless include has "text").

## `language` (type: `string`):

EU language code of the text and titles: BG, CS, DA, DE, EL, EN, ES, ET, FI, FR, GA, HR, HU, IT, LT, LV, MT, NL, PL, PT, RO, SK, SL, SV. Default EN. If the text is missing in that language, English is returned with a warning. E.g. "DE".

## `asOf` (type: `string`):

YYYY-MM-DD, e.g. "2025-01-01": return the consolidated version that applied on that date. Empty = today (the newest consolidated version in force now). Acts without consolidated versions return the Official Journal text.

## `include` (type: `array`):

Any of "metadata" (always on), "amendments" (amended_by, corrected_by, repealed_by, amends, repeals), "citing" (acts and judgments that cite this act, newest first) and "text" (the whole act as plain text, cut at maxTextChars). Default \["metadata", "amendments"]. The price is the same.

## `maxTextChars` (type: `integer`):

Cap on article_text and text, in characters, e.g. 30000 (default). Longer text is cut and flagged (article_text_truncated / text_truncated) with a warning.

## `maxCiting` (type: `integer`):

With include "citing": how many citing acts to list, newest first, e.g. 20 (default). citing_acts_total always gives the full count.

## `ojSince` (type: `string`):

Switches to Official Journal mode: list acts published in the OJ L series from this date (YYYY-MM-DD, e.g. "2026-11-03") until today, newest first, at most 31 days back. Leave query empty when you use this. Empty = normal lookup.

## `keywords` (type: `string`):

OJ mode only: comma-separated words or phrases; an act is kept when its title (in the chosen language) contains any of them, case-insensitive, e.g. "artificial intelligence, data". Empty = all acts.

## `maxResults` (type: `integer`):

OJ mode only: the most acts to return, newest first, e.g. 50 (default). One charge per act returned.

## Actor input object example

```json
{
  "query": "GDPR",
  "article": "5",
  "language": "EN",
  "include": [
    "metadata",
    "amendments"
  ],
  "maxTextChars": 30000,
  "maxCiting": 20,
  "maxResults": 50
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "query": "GDPR",
    "article": "5"
};

// Run the Actor and wait for it to finish
const run = await client.actor("bosco_labs/eu-law-lookup").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "query": "GDPR",
    "article": "5",
}

# Run the Actor and wait for it to finish
run = client.actor("bosco_labs/eu-law-lookup").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "query": "GDPR",
  "article": "5"
}' |
apify call bosco_labs/eu-law-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bosco_labs/eu-law-lookup"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/30Evt7xinEk8U35Ou/builds/u2YwE6Qzun6c57tKg/openapi.json
