Is this EU act in force? Resolve it by CELEX or ELI

An agent reasoning about EU law needs the consolidated act or article text at a date, addressed by its stable identifier — CELEX or ELI — not a paraphrase from memory. One call returns text, status and validity window.

An agent that reasons about EU law should not pull the text of a regulation from its own weights. EU acts are consolidated and amended over time, and a model’s recollection is a paraphrase with no version, no date, and no way to tell whether it is still the law. The reliable move is to address the act by its stable identifier — CELEX or ELI — and resolve the consolidated text in force on a date. One paid call — GET /legal/eu-act — returns the text, its status, and the validity window it applies to.

The problem: EU law is identifier-addressed and time-scoped

European law has two properties that defeat recall and reward lookup. First, each act has a stable identifier: a CELEX number (32016R0679 for the GDPR) or an ELI (eli/reg/2016/679/oj). That identifier — not a title an agent half-remembers — is the correct key. Second, an act is consolidated over time: the wording of an article on one date is not the wording on another. “Is this in force?” is only meaningful relative to a date.

The consolidated EUR-Lex / Cellar corpus that holds this is bulky, versioned reference data. It is exactly what should be looked up against a known snapshot rather than stored in a model.

The call: text, status and validity for an identifier and date

GET /legal/eu-act takes a celex or an eli, an optional article, and an optional date (defaults to today). Omit article to resolve the act head:

GET /legal/eu-act?celex=32016R0679&article=17&date=2026-01-01
GET /legal/eu-act?eli=eli/reg/2016/679/oj&article=17

It returns the consolidation in force on that date:

FieldWhat the agent learns
textConsolidated text of the version in force on the date
etatStatus, carried as stored — never reinterpreted
dateThe effective resolution date
versionThe selected consolidation’s id and validity window
coverageWhether the store served an unambiguous consolidation

Provide at least one identifier; if both celex and eli are supplied, CELEX is used as the lookup key and both are echoed back. The version block — date_debut (inclusive) and date_fin (exclusive, omitted when current) — bounds exactly the window the returned text governs, which is what makes the citation auditable.

A covered date is a 200, even for an expired consolidation

The honesty point for legal grounding: if the requested date falls inside a historical consolidation’s validity window, the answer is a 200 — the service returns the text that was in force then, with the stored etat and the date_fin that closed it. It does not convert a non-current status into an HTTP error.

Per the x402 golden rule, the agent pays for the answer to its question. “Here is the text that applied on 2005-01-01, and its window ended 2016-07-01” is a successful answer. The 4xx range is reserved for questions the service cannot answer:

  • INVALID_REF — neither celex nor eli was supplied.
  • INVALID_DATEdate is not YYYY-MM-DD.
  • UNKNOWN_ACT / UNKNOWN_ARTICLE — the identifier or article does not exist.
  • NO_VERSION_AT_DATE — the act exists, but no consolidation covers that date.

So an agent must read version.date_fin and etat, not just the 200: a historical version is a valid answer to “what applied then,” not a statement that it is current law.

Coverage honesty: what it will not do

The endpoint answers from a local snapshot of EUR-Lex / Cellar (freshness.kind: "snapshot", as_of the dump date). It does not fetch EUR-Lex at request time, search by keyword, interpret case law, translate missing language versions, or infer absent articles. The first public version serves English text. etat is carried verbatim as legal metadata, and coverage.complete: false is reserved for genuine source anomalies (e.g. overlapping versions) — never a guess. Unknown acts and uncovered dates are 4xx, not partial paid answers.

Where it sits in the x402 loop

Grounding is the lookup before the agent commits to a statement about EU law. The loop:

  1. Discover the endpoint and call it; receive the 402.
  2. Pay — sign the chosen rail and replay the request.
  3. Resolve — read text, etat, and the version window.
  4. Branch — cite the text only when it is in force for the date; flag an expired or future consolidation; on NO_VERSION_AT_DATE, report that no version applied rather than inventing one.

Each paid call follows the same x402 pattern as every Invoket endpoint. The Quickstart walks the whole discover → 402 → pay → replay cycle with runnable snippets. Price and accepted rails are not pinned in this article — they are served live by the catalog; see the endpoint reference for the current figure.

GET /legal/eu-act is the EU counterpart to the French-law endpoint, and sits alongside the time-travel lookups:

Used for what it is — a grounded, identifier-addressed, date-scoped lookup of EU law — GET /legal/eu-act lets an agent quote a regulation it can stand behind, with the validity window attached. For the full field reference and error codes, see the GET /legal/eu-act documentation; for how agents discover and call Invoket endpoints, see For agents.

EU law data is derived from EUR-Lex / Cellar made available by the Publications Office of the European Union; reuse must preserve attribution to the European Union and EUR-Lex.