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" }
]
}
| Field | Type | Required | Description |
|---|---|---|---|
refs | object[] | yes | Legal references to resolve, 1 to 50 entries |
Each item is either a French reference or an EU reference:
| Field | Type | Required | Description |
|---|---|---|---|
code | string | FR | French text identifier, for example code-civil |
article | string | FR only | Article number for code; optional for EU act-level lookups |
celex | string | EU id | CELEX identifier, for example 32016R0679 |
eli | string | EU id | ELI identifier, used when celex is absent |
date | string | no | UTC 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 toresults.length.results: one verdict per input item, in the same order as the input. Covered items have the same field shape as thedataofGET /legal/articleorGET /legal/eu-act: echoed identifiers,date,label,etat,text,versionandcoverage.- Unknown or date-uncovered items remain item-level verdicts in the 200 response.
They echo the resolvable identifiers and
date, setcoverage.completetofalse, and omit fields that cannot be served, such asetat,textandversion. - A single
provenanceblock covers the whole batch. When the batch touches both legal corpora,provenance.sourcenames both;freshness.kindremainssnapshot.
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.
| Status | code | Case |
|---|---|---|
| 400 | INVALID_BODY | Body missing or not JSON, not an object, or refs missing |
| 400 | EMPTY_BATCH | refs is an empty array ([]) |
| 400 | BATCH_TOO_LARGE | More than 50 references in a single call |
| 400 | INVALID_REF | An item is malformed, including an invalid date; error names refs[i] |
| 500 | INTERNAL | Internal 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
/catalogand how settlement works.