Legislation API

Spanish legislation API: the article in force on a date, as JSON

Ask for an article the way it is really cited —“art. 59.3 ET”, “ET 59”, “1902 CC”— and get the BOE consolidated text in force on the date you give, with its validity period and the official link. Also every wording and the law on the date of the facts.

Access status

Access is open

Create your developer account, confirm your email and enable two-factor authentication (mandatory) to create your key. The library, calculators and deadlines do not use balance; companies and assistant come with 100 trial queries, no card needed.

Access will be for verified businesses worldwide.

Who it is for

  • Legal tech and law-firm software that must cite current law without maintaining its own database of statutes.
  • Teams building legal assistants or search tools that want sources with citation, version and official link.
  • Legal departments and consultancies with a technical team that automate regulatory checks.
  • Research and teaching that need to compare an article’s wording on different dates.

What you can do

An article by its citation

It understands “art. 59.3 ET”, “ET 59” or “1902 CC” and returns the text in force on the requested date (by default, today) with its statute, its block, its validity period and the official link. When abbreviations repeat, the orden parameter disambiguates.

Every wording

The versions of an article from oldest to newest, each with its validity period and its source, and any gaps or overlaps between them.

The law on the date of the facts

The wording in force on the day of the facts and all later ones. In criminal law it warns that later reforms must be weighed (Criminal Code art. 2.2) but does not decide which is more favourable: that is a legal judgement and the result is born propuesto (proposed).

Text search

Search the loaded legislation on a date, from most to least relevant. If nothing matches, the list is empty: an article is never made up.

Which statutes are loaded

GET /v1/dev/biblioteca/abreviaturas lists the verified abbreviations that have articles and how many each statute has: it is counted, not declared.

The operations

  • GET/biblioteca/abreviaturas

    Loaded legislation: verified abbreviations and article counts Details (Spanish)

    Free
  • GET/biblioteca/articulo

    An article by its citation, as in force on a date Details (Spanish)

    Free
  • GET/biblioteca/buscar

    Text search over the loaded legislation Details (Spanish)

    Free
  • GET/biblioteca/versiones

    Every wording of an article, with its validity period and source Details (Spanish)

    Free
  • GET/biblioteca/ley-en-fecha

    The wording in force on the date of the facts and all later ones Details (Spanish)

    Free

Request and response examples

The examples read your key from the JURILIA_API_KEY environment variable.

An article on a date

The four outcomes (encontrado, abreviatura_desconocida, articulo_no_esta, no_vigente_esa_fecha) travel with 200: “not found” is information.

curl

curl "https://api.jurilia.com/v1/dev/biblioteca/articulo?cita=ET+59&fecha=2026-01-01" \
  -H "Authorization: Bearer $JURILIA_API_KEY"

Python

import os
import requests

r = requests.get(
    "https://api.jurilia.com/v1/dev/biblioteca/articulo",
    headers={"Authorization": f"Bearer {os.environ['JURILIA_API_KEY']}"},
    params={"cita":"ET 59","fecha":"2026-01-01"},
    timeout=30,
)
r.raise_for_status()
print(r.json())

JavaScript

const url = new URL("https://api.jurilia.com/v1/dev/biblioteca/articulo");
url.search = new URLSearchParams({"cita":"ET 59","fecha":"2026-01-01"});
const r = await fetch(url, {
  headers: { Authorization: `Bearer ${process.env.JURILIA_API_KEY}` },
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
console.log(await r.json());

Response (the shape; the values are examples)

{
  "desenlace": "encontrado",
  "abreviatura": "ET",
  "articulo": "59",
  "fecha": "2026-01-01",
  "boeId": "BOE-A-…",
  "bloqueId": "…",
  "tituloNorma": "…",
  "tituloBloque": "…",
  "texto": "…",
  "vigenciaDesde": "AAAA-MM-DD",
  "vigenciaHasta": null,
  "urlOficial": "https://www.boe.es/…",
  "aviso": null
}

The values are illustrative so you can see the exact shape of the response; they are not data from a real query.

The law on the date of the facts

The wording in force when the facts happened and the later ones up to the reference date.

curl

curl "https://api.jurilia.com/v1/dev/biblioteca/ley-en-fecha?articulo=ET+59&fechaHechos=2019-05-01&fechaReferencia=2026-10-01" \
  -H "Authorization: Bearer $JURILIA_API_KEY"

Python

import os
import requests

r = requests.get(
    "https://api.jurilia.com/v1/dev/biblioteca/ley-en-fecha",
    headers={"Authorization": f"Bearer {os.environ['JURILIA_API_KEY']}"},
    params={"articulo":"ET 59","fechaHechos":"2019-05-01","fechaReferencia":"2026-10-01"},
    timeout=30,
)
r.raise_for_status()
print(r.json())

JavaScript

const url = new URL("https://api.jurilia.com/v1/dev/biblioteca/ley-en-fecha");
url.search = new URLSearchParams({"articulo":"ET 59","fechaHechos":"2019-05-01","fechaReferencia":"2026-10-01"});
const r = await fetch(url, {
  headers: { Authorization: `Bearer ${process.env.JURILIA_API_KEY}` },
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
console.log(await r.json());

Response (the shape; the values are examples)

{
  "desenlace": "encontrado",
  "abreviatura": "CP",
  "articulo": "…",
  "articuloConVersiones": { "…": "como en /versiones" },
  "enLaFecha": {
    "fechaHechos": "AAAA-MM-DD",
    "fechaReferencia": "AAAA-MM-DD",
    "vigenteEnLosHechos": { "…": "una versión" },
    "posteriores": [],
    "vigenteEnLaReferencia": { "…": "una versión" },
    "aviso": null,
    "estado": "propuesto"
  },
  "fundamento": null
}

The values are illustrative so you can see the exact shape of the response; they are not data from a real query.

Search articles by text

orden brings results closer to a jurisdiction; it does not filter.

curl

curl "https://api.jurilia.com/v1/dev/biblioteca/buscar?q=despido+improcedente&orden=social" \
  -H "Authorization: Bearer $JURILIA_API_KEY"

Python

import os
import requests

r = requests.get(
    "https://api.jurilia.com/v1/dev/biblioteca/buscar",
    headers={"Authorization": f"Bearer {os.environ['JURILIA_API_KEY']}"},
    params={"q":"despido improcedente","orden":"social"},
    timeout=30,
)
r.raise_for_status()
print(r.json())

JavaScript

const url = new URL("https://api.jurilia.com/v1/dev/biblioteca/buscar");
url.search = new URLSearchParams({"q":"despido improcedente","orden":"social"});
const r = await fetch(url, {
  headers: { Authorization: `Bearer ${process.env.JURILIA_API_KEY}` },
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
console.log(await r.json());

Response (the shape; the values are examples)

{
  "articulos": [
    {
      "boeId": "BOE-A-…",
      "bloqueId": "…",
      "tituloNorma": "…",
      "abreviatura": "ET",
      "articulo": "56",
      "tituloBloque": "…",
      "texto": "…",
      "vigenciaDesde": "AAAA-MM-DD",
      "vigenciaHasta": null,
      "urlOficial": "https://www.boe.es/…"
    }
  ]
}

The values are illustrative so you can see the exact shape of the response; they are not data from a real query.

Why you can trust what it returns

Cite or stay silent

Every article carries its statute, version, validity period and official link. If it is not there, the response says so; nothing is made up.

The date rules

The text is not “today’s” but the one in force on the date you ask for, and you can walk through every wording.

Free

The library uses neither balance nor the trial: it only asks for your key and respects the per-minute limit.

Limits and what it does not do

  • The BOE consolidated text is informative and has no official value: for legal purposes, the official publication. That is why every response carries the link.
  • Only the loaded legislation: /biblioteca/abreviaturas says which.
  • It does not decide which rule is more favourable or interpret anything: it returns text with its source.
  • 120 calls per minute per key.

Price

Free. It asks for your key and respects the limit of 120 calls per minute, but uses neither balance nor the trial.

Authentication and errors

Every call carries the key of your developer account in the header Authorization: Bearer iuris_sk_…. The base address is https://api.jurilia.com. There is a limit of 120 calls per minute per key, with the headers X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset on every response. A key can carry an allow-list of IPs or networks (CIDR).

Failures come as JSON with a stable code: 401 (missing or invalid key), 402 (no balance: not served and not charged), 403 (IP not allowed), 409 (a datum that decides the calculation is missing: not charged) and 429 (too many calls in a row).

Frequently asked questions

Can I ask for an article by its citation?
Yes: “art. 59.3 ET”, “ET 59” or “1902 CC”. If it is not understood which article is meant, 400 or 422 depending on the endpoint; if it is understood and not there, 200 with articulo_no_esta.
Can I get the text in force on a past date?
Yes. fecha on /biblioteca/articulo and fechaHechos on /biblioteca/ley-en-fecha return the wording in force that day, with its validity period.
Does the returned text have official value?
No: the BOE consolidated text is informative. Every result carries the official link so you can check it against the publication.
How much does it cost?
Nothing: the library is free. You only need the key of your developer account.