GET /legal/eu-act
Returns the consolidated version of a European Union act or article in force at a given date: text, status, validity dates and coverage metadata. The lookup is served from a local store built from EUR-Lex / Cellar data, so a covered reference resolves in milliseconds without an account or API key. The corpus currently covers a selected set of EU acts and is expanding; an uncovered reference returns 404, never a paid empty answer.
Use it when an agent needs grounded EU law text it should not infer from memory:
the consolidated wording of a regulation, a directive article at a date, or the
validity window of a served consolidation. See the live
/catalog for the authoritative endpoint listing and price.
x402 golden rule: the agent pays for the answer to its question. A known
act or article with a consolidation covering the requested date is a successful
answer -> 200, even when the stored etat says the version is no longer the
current legal state - in_force_at_date says so explicitly. Requests the service
cannot answer - missing identifiers, invalid dates, unknown acts, unknown
articles, or a date no consolidation covers and no repeal explains - leave the
200 range.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
celex | string | one identifier | CELEX identifier, for example 32016R0679; case-insensitive |
eli | string | one identifier | ELI identifier; used when celex is absent |
article | string | no | Article number within the act, for example 17; omit to resolve the whole act |
date | string | no | UTC date to resolve, strict format YYYY-MM-DD; defaults to today’s date |
Provide at least one of celex or eli. If both are present, CELEX is used as
the lookup identifier and both supplied identifiers are echoed in data. The
celex is case-insensitive: 32016r0679 and 32016R0679 resolve to the same
act, and the response echoes the canonical uppercase form.
GET /legal/eu-act?celex=32016R0679&article=17&date=2026-01-01
Resolve the whole act by omitting article:
GET /legal/eu-act?celex=32016R0679
Use ELI when the caller does not have a CELEX identifier:
GET /legal/eu-act?eli=eli/reg/2016/679/oj&article=17
200 response - UnifiedResponse
{
"data": { ... },
"provenance": {
"source": "eur-lex-cellar",
"fetched_at": "2026-06-20T12:00:00Z",
"freshness": { "kind": "snapshot", "as_of": "2026-06-01T00:00:00Z" }
}
}
provenance.source: source identifier from the served EUR-Lex store, commonlyeur-lex-cellar.freshness.kind:snapshot;as_ofis the EUR-Lex dump date that backed the answer. Freshness is dated per dataset, so an EU answer reflects the EUR-Lex snapshot date, independent of the French corpus.- EU law data is derived from EUR-Lex / Cellar data and must be reused with attribution to the European Union / Publications Office.
Fields of data
| Field | Type | Description |
|---|---|---|
celex | string | Echoed when the request supplied celex |
eli | string | Echoed when the request supplied eli |
article | string | Echoed when the request supplied an article number |
date | string | Effective resolution date in YYYY-MM-DD form |
label | string | Human label for the resolved act or article |
etat | string | Status carried as stored, never reinterpreted by the service |
in_force_at_date | bool | Whether the served text is the applicable law on date |
applicable_from | string | null | Date the act, or that specific article, becomes applicable - not the same as being in force |
applicable_at_date | bool | null | Whether it was applicable on date; null when applicable_from is null |
applicability_scope | string | null | "act" when the date is the act’s own application date, "article" when a derogation names that article |
applicability_source | string | null | Citation of the provision carrying the date, so the verdict is checkable |
text | string | Consolidated text of the selected version; article level only (when article is supplied) |
articles | string array | Article numbers available at the date; act level only (when article is omitted) |
version | object | Validity period and source version identifier |
coverage_window | object | Period over which this act is actually queryable: from (inclusive), to (exclusive, null when open) |
coverage | object | Completeness marker for the served consolidation |
data has two shapes. With an article, the response carries text (the
consolidated article text). Without an article, it resolves the act and
carries articles — the list of article numbers available at that date — with
the act’s status and validity dates, but no text: the act never concatenates
article texts, and each article’s text stays on ?article=.
celex, eli and article are omitted when they were not supplied. The first
public version serves English text from the local store; if a source-store
limitation or anomaly affects the served content, coverage.reason explains it
without inventing missing law.
In force is not the same as applicable
An EU regulation enters into force shortly after publication, but it often applies later - and, increasingly, in stages, article by article. The GDPR entered into force on 2016-05-24 and applied from 2018-05-25. The AI Act has been in force in its entirety since 2024-08-01, yet its Article 5 applies from 2025-02-02 and its Article 50 only from 2026-08-02.
etat and in_force_at_date answer is this text in force. The four
applicab* fields answer the question a compliance agent actually asks: does
this apply to me on that date - so a 200 with etat: "vigueur" is never read
as an unqualified “yes”.
These dates are not in the EUR-Lex metadata: no EU dataset publishes an
application date per article. They are curated from each act’s own final
provisions (“Entry into force and application”) and every answer carries the
citation it came from in applicability_source.
When no application date is on record for an act - or when the act sets no
determined date, as with a directive that takes effect through national
transposition measures - the four fields are null and coverage.reason says
why. A date is never guessed. Staggered dates that apply to a single
paragraph (AI Act Article 6(1), DSA Article 24(2)) are not modelled: such an
article carries its act’s date, which is the date it applies in full - never an
earlier one than reality.
version
| Field | Type | Description |
|---|---|---|
version_id | string | Stable identifier of the selected source version |
date_debut | string | Start date of this version, inclusive, in YYYY-MM-DD |
date_fin | string | null | End date of this version, exclusive; omitted when current |
coverage
| Field | Type | Description |
|---|---|---|
complete | bool | true when the store served an unambiguous consolidation |
reason | string | Present when complete: false, naming the source dump anomaly |
Example - article in force
{
"data": {
"celex": "32016R0679",
"article": "17",
"date": "2026-01-01",
"label": "Regulation (EU) 2016/679 (GDPR), Article 17",
"etat": "vigueur",
"in_force_at_date": true,
"applicable_from": "2018-05-25",
"applicable_at_date": true,
"applicability_scope": "act",
"applicability_source": "Regulation (EU) 2016/679, Article 99(2): \"It shall apply from 25 May 2018.\"",
"text": "right to erasure",
"version": {
"version_id": "32016R0679-art-17-v1",
"date_debut": "2018-05-25"
},
"coverage": { "complete": true }
},
"provenance": {
"source": "eur-lex-cellar",
"fetched_at": "2026-06-20T12:00:00Z",
"freshness": { "kind": "snapshot", "as_of": "2026-06-01T00:00:00Z" }
}
}
Example - whole act
When article is omitted, the service resolves the act and returns its
status, validity dates and the list of article numbers available at that date.
There is no text field at act level; fetch any article’s text by adding
?article=.
{
"data": {
"celex": "32016R0679",
"date": "2026-01-01",
"label": "32016R0679",
"etat": "vigueur",
"in_force_at_date": true,
"articles": ["1", "2", "3", "17"],
"version": {
"version_id": "32016R0679-20180525",
"date_debut": "2018-05-25"
},
"coverage": { "complete": true }
},
"provenance": {
"source": "eur-lex-cellar",
"fetched_at": "2026-06-20T12:00:00Z",
"freshness": { "kind": "snapshot", "as_of": "2026-06-01T00:00:00Z" }
}
}
Example - in force, not yet applicable
The AI Act is in force in its entirety, so its Article 50 resolves to a 200
with etat: "vigueur". Read on its own, that answer would be misleading: the
article does not apply until 2026-08-02.
{
"data": {
"celex": "32024R1689",
"article": "50",
"date": "2026-01-01",
"label": "Regulation (EU) 2024/1689 (AI Act), Article 50",
"etat": "vigueur",
"in_force_at_date": true,
"applicable_from": "2026-08-02",
"applicable_at_date": false,
"applicability_scope": "act",
"applicability_source": "Regulation (EU) 2024/1689, Article 113: \"It shall apply from 2 August 2026.\"",
"text": "transparency obligations for providers and deployers of certain AI systems ...",
"version": {
"version_id": "32024R1689-art-50-v1",
"date_debut": "2024-08-01"
},
"coverage": { "complete": true }
},
"provenance": {
"source": "eur-lex-cellar",
"fetched_at": "2026-06-20T12:00:00Z",
"freshness": { "kind": "snapshot", "as_of": "2026-06-01T00:00:00Z" }
}
}
Asking for Article 5 instead returns applicable_from: "2025-02-02" with
applicability_scope: "article": Chapters I and II of the AI Act are covered by
a derogation that names them, and the response cites it.
Example - expired consolidation within its validity window
If the requested date is covered by a historical consolidation, the answer is a 200. The service exposes the stored status and validity dates; it does not convert a non-current status into an HTTP error.
{
"data": {
"celex": "31999L0093",
"article": "1",
"date": "2005-01-01",
"label": "Directive 1999/93/EC, Article 1 (repealed)",
"etat": "vigueur",
"in_force_at_date": true,
"text": "e-signatures (expired)",
"version": {
"version_id": "31999L0093-art-1-v1",
"date_debut": "2000-01-19",
"date_fin": "2016-07-01"
},
"coverage": { "complete": true }
},
"provenance": {
"source": "eur-lex-cellar",
"fetched_at": "2026-06-20T12:00:00Z",
"freshness": { "kind": "snapshot", "as_of": "2026-06-01T00:00:00Z" }
}
}
Example - article deleted by an amending act
An article removed from an act by a later act (for example Articles 12-15 of the
e-Commerce Directive, replaced by the Digital Services Act on 2024-02-17) still
answers 200: the last known wording is served, and in_force_at_date: false
states that it is no longer the applicable law. That flag is the one to branch
on. Deducing it from etat and the validity dates is genuinely error-prone,
because the two corpora encode a repeal in opposite ways: EU law opens a repeal
version that starts at the repeal, French law closes the last version’s
interval instead. /legal/article and /legal/eu-act answer the same question
the same way, at the same price.
{
"data": {
"celex": "32000L0031",
"article": "14",
"date": "2026-07-25",
"label": "Directive 2000/31/EC, Article 14",
"etat": "abroge",
"in_force_at_date": false,
"text": "...last known wording before deletion...",
"version": {
"version_id": "32000L0031-art-14-abroge",
"date_debut": "2024-02-17"
},
"coverage": { "complete": true }
},
"provenance": {
"source": "eur-lex-cellar",
"fetched_at": "2026-07-25T12:00:00Z",
"freshness": { "kind": "snapshot", "as_of": "2026-07-20T00:00:00Z" }
}
}
Coverage honesty
The service answers from a local snapshot of EUR-Lex / Cellar data. It does not
fetch EUR-Lex at request time, search by keyword, interpret case law, translate
missing language versions or infer absent articles. etat is carried from the
source store as legal metadata; callers should treat it as the authoritative
status for the selected consolidation.
coverage.complete: false is reserved for source-store anomalies, such as
overlapping versions where the service selected the most recent start date.
Unknown acts, unknown articles and dates not covered by any known consolidation
are not partial paid answers: they return 4xx errors.
The service distinguishes an act that is out of scope from an article
number that does not exist inside a covered act. When the act itself is not in
the store, the error is UNKNOWN_ACT — even if an article was supplied, since
it is the act that is missing, not the article. When the act is covered but the
article number is unknown, it is UNKNOWN_ARTICLE. The covered set of EU acts
is listed in the live /catalog entry.
Historical depth varies per act
Consolidated EU law is published act by act, and the Publications Office does
not publish every past state of every act. coverage_window reports, on every
answer, the period this act can actually be read over: from inclusive, to
exclusive (null when the window is still open).
The e-Commerce Directive is the sharpest case: in force since 2000, it is only
queryable from 2024-02-17, because neither the base act nor the 2000
consolidation is published in any manifestation we can retrieve. Asking for an
earlier date returns OUT_OF_COVERAGE_WINDOW — a limit on our coverage, not
a statement that the law did not exist:
{
"error": "act `32000L0031` is covered from 2024-02-17 onwards; the store has no data for 2020-01-01. Historical depth varies per act: this is a coverage limit, not a statement about the law",
"code": "OUT_OF_COVERAGE_WINDOW"
}
Inside the window, a date that no consolidation covers stays
NO_VERSION_AT_DATE: the act is covered, that article simply had no version
then. Both are 4xx and neither is billed. Windows are derived from the versions
actually served, so they never promise more than the store holds — and
/legal/history returns the same window with the
timeline, so a monitoring agent knows how far back to go before spending a call.
Errors
Only requests the service cannot answer leave the 200 range.
| Status | code | Case |
|---|---|---|
| 400 | INVALID_REF | Both celex and eli are missing or empty |
| 400 | INVALID_DATE | date is present but not strictly formatted as YYYY-MM-DD (zero-padded: 2026-07-05, not 2026-7-5) |
| 404 | UNKNOWN_ACT | The act identifier is well formed but no matching act exists, even when an article is supplied |
| 404 | UNKNOWN_ARTICLE | The act is covered, but the requested article is not present in it |
| 404 | OUT_OF_COVERAGE_WINDOW | The date falls outside the act’s coverage_window — that period is not covered for this act |
| 404 | NO_VERSION_AT_DATE | Within the window, the act or article exists but no consolidation covers the date and no repeal explains the gap |
| 500 | INTERNAL | Internal error (detail logged, not exposed) |
{ "error": "query parameter `celex` (e.g. `32016R0679`) or `eli` is required", "code": "INVALID_REF" }
{ "error": "invalid `date` `2018`; expected ISO calendar format YYYY-MM-DD", "code": "INVALID_DATE" }
{ "error": "no act `39999R9999` found in the store", "code": "UNKNOWN_ACT" }
An unknown act with an article still reports the missing act, not a missing
article:
{ "error": "no act `32099R9999` found in the store", "code": "UNKNOWN_ACT" }
{ "error": "no article `999` found in act `32016R0679`", "code": "UNKNOWN_ARTICLE" }
{ "error": "Directive 1999/93/EC, Article 1 (repealed) has no consolidated version in force on 2020-01-01", "code": "NO_VERSION_AT_DATE" }
Attribution
EU law data is derived from EUR-Lex / Cellar data made available by the Publications Office of the European Union. Reuse must preserve attribution to the European Union and EUR-Lex.
See also
GET /legal/article- French law article text in force at a date from the LEGI dataset.- For agents - discovery surfaces, the live
/catalogand how settlement works.