POST /legal/article/batch

Checks a list of legal references in a single call: up to 50 references, settled with one x402 payment for the whole batch. Each entry runs through the same local lookup engines as GET /legal/article for French LEGI articles and GET /legal/eu-act for EU CELEX/ELI acts or articles.

Use it when an agent needs to review a contract, audit a citation list or check compliance evidence without issuing one paid call per citation. The lookup is served from local legal snapshots: no account, no API key and no network fetch to Legifrance or EUR-Lex at request time.

The call is priced by reference with a single x402 settlement for the whole batch: a base plus a per-reference unit, capped at 50 references. See the live /catalog for the authoritative amounts and accepted rails; this page intentionally does not freeze price figures.

x402 golden rule: the agent pays for the answer to its question. A well-formed batch is a successful answer -> 200, even when some references are repealed, unknown or not covered at the requested date. Those cases are reported per item with etat or coverage.complete: false. The 4xx range is reserved for requests the service cannot answer as a batch: missing or malformed body, empty list, batch over the cap or malformed items.

Request

POST with a JSON body. Set Content-Type: application/json.

POST /legal/article/batch
Content-Type: application/json
{
  "refs": [
    { "code": "code-civil", "article": "1240", "date": "2024-01-01" },
    { "celex": "32016R0679", "article": "17" }
  ]
}
FieldTypeRequiredDescription
refsobject[]yesLegal references to resolve, 1 to 50 entries

Each item is either a French reference or an EU reference:

FieldTypeRequiredDescription
codestringFRFrench text identifier, for example code-civil
articlestringFR onlyArticle number for code; optional for EU act-level lookups
celexstringEU idCELEX identifier, for example 32016R0679
elistringEU idELI identifier, used when celex is absent
datestringnoUTC date to resolve, format YYYY-MM-DD; defaults to request date

For French references, provide code and article. For EU references, provide at least one of celex or eli; article is optional when resolving the act head. If an item contains a non-empty code, it is treated as French.

200 response - UnifiedResponse

{
  "data": {
    "count": 2,
    "results": [ { ... }, { ... } ]
  },
  "provenance": {
    "source": "legifrance-legi + eur-lex-cellar",
    "fetched_at": "2026-06-20T12:00:00Z",
    "freshness": { "kind": "snapshot", "as_of": "2026-06-01T00:00:00Z" }
  }
}
  • count: number of submitted references, equal to results.length.
  • results: one verdict per input item, in the same order as the input. Covered items have the same field shape as the data of GET /legal/article or GET /legal/eu-act: echoed identifiers, date, label, etat, text, version and coverage.
  • Unknown or date-uncovered items remain item-level verdicts in the 200 response. They echo the resolvable identifiers and date, set coverage.complete to false, and omit fields that cannot be served, such as etat, text and version.
  • A single provenance block covers the whole batch. When the batch touches both legal corpora, provenance.source names both; freshness.kind remains snapshot.

See the single-call references for the full field tables, status semantics and attribution rules for French LEGI and EU law data.

Example - mixed French and EU batch

{
  "data": {
    "count": 2,
    "results": [
      {
        "code": "code-civil",
        "article": "1240",
        "date": "2024-01-01",
        "label": "Code civil, art. 1240",
        "etat": "vigueur",
        "text": "Tout fait quelconque de l'homme, qui cause a autrui un dommage, oblige celui par la faute duquel il est arrive a le reparer.",
        "version": {
          "version_id": "LEGIARTI000032041571",
          "date_debut": "2016-10-01"
        },
        "coverage": { "complete": true }
      },
      {
        "celex": "32016R0679",
        "article": "17",
        "date": "2026-06-20",
        "label": "Regulation (EU) 2016/679 (GDPR), Article 17",
        "etat": "vigueur",
        "text": "right to erasure",
        "version": {
          "version_id": "32016R0679-art-17-v1",
          "date_debut": "2018-05-25"
        },
        "coverage": { "complete": true }
      }
    ]
  },
  "provenance": {
    "source": "legifrance-legi + eur-lex-cellar",
    "fetched_at": "2026-06-20T12:00:00Z",
    "freshness": { "kind": "snapshot", "as_of": "2026-06-01T00:00:00Z" }
  }
}

Example - unknown reference is still a 200 item verdict

In a well-formed batch, an unknown article or a known article with no version at the requested date does not fail the whole request. It is returned as an incomplete verdict.

{
  "data": {
    "count": 1,
    "results": [
      {
        "code": "code-civil",
        "article": "9999",
        "date": "2026-01-01",
        "coverage": {
          "complete": false,
          "reason": "`code-civil-art-9999` is not covered by the store"
        }
      }
    ]
  },
  "provenance": {
    "source": "legifrance-legi",
    "fetched_at": "2026-06-20T12:00:00Z",
    "freshness": { "kind": "snapshot", "as_of": "2026-06-01T00:00:00Z" }
  }
}

Repealed or historical versions are also successful item verdicts when the store covers the requested date. The status lives in etat; it is not converted into an HTTP error.

Volume pricing

This endpoint uses per-unit pricing: one x402 settlement for the request, with the payable amount derived from the number of references in refs (base plus per-reference unit, capped at 50). The gateway counts the array length; it does not inspect legal content to compute price.

The live /catalog is the price authority and exposes the current base, unit, maximum units, accepted assets and networks. Do not cache amounts from this page; they are deliberately not repeated here.

Errors

Only requests the service cannot answer leave the 200 range. The cap is checked before any resolution, so an oversized batch is rejected without being billed an answer.

StatuscodeCase
400INVALID_BODYBody missing or not JSON, not an object, or refs missing
400EMPTY_BATCHrefs is an empty array ([])
400BATCH_TOO_LARGEMore than 50 references in a single call
400INVALID_REFAn item is malformed, including an invalid date; error names refs[i]
500INTERNALInternal error (detail logged, not exposed)
{ "error": "request body must be a JSON object with a `refs` array", "code": "INVALID_BODY" }
{ "error": "batch `refs` must contain at least one reference", "code": "EMPTY_BATCH" }
{ "error": "batch `refs` exceeds the maximum of 50 references", "code": "BATCH_TOO_LARGE" }
{ "error": "refs[1]: reference must provide `code`+`article` (FR) or `celex`/`eli` (EU)", "code": "INVALID_REF" }

See also

  • GET /legal/article - French law article text in force at a date from the LEGI dataset.
  • GET /legal/eu-act - EU act or article text in force at a date from EUR-Lex / Cellar data.
  • For agents - discovery surfaces, the live /catalog and how settlement works.