# JORF Scraper: French Official Journal API (Legifrance + DILA) (`dltik/jorf-bulletin-officiel-scraper`) Actor

Scrape the Journal Officiel de la République Française (JORF). Get decrets, lois, arretes by date range or NOR. Full text, NATURE, NOR, ELI URI, MINISTERE, SIGNATAIRES, Legifrance URLs. Compliance, lawtech, public-affairs. $0.005/article.

- **URL**: https://apify.com/dltik/jorf-bulletin-officiel-scraper.md
- **Developed by:** [Walid](https://apify.com/dltik) (community)
- **Categories:** Business, Developer tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.00005 / actor start

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## JORF Scraper — Journal Officiel de la France API (Legifrance + DILA)

⭐ **Bookmark this actor → [apify.com/dltik/jorf-bulletin-officiel-scraper](https://apify.com/dltik/jorf-bulletin-officiel-scraper)** — Apify ranks by bookmarks, so it directly drives the visibility of this scraper. **One click. No signup beyond your existing Apify account.**

> Scrape the **Journal Officiel de la République Française (JORF)** — every decret, loi, arrete, ordonnance, decision and avis published in France. **Search by date range, NATURE, ministry or NOR code.** Get full body text, ELI URI, signataires, Legifrance URL, ministere — all the structured fields compliance, lawtech and public-affairs teams need. **No OAuth, no API key, no quota.** Built on the official **DILA open data feed**.

### ✨ What makes this scraper different

| Feature | This scraper | Generic FR gov scrapers |
|---|:---:|:---:|
| Official DILA JORFSIMPLE feed (authoritative source) | ✅ | ❌ HTML scraping |
| Per-article structured records (not raw HTML) | ✅ | ❌ |
| Full body text reconstructed article-by-article | ✅ | ❌ partial |
| NOR, ELI URI + ELI alias, SIGNATAIRES extracted | ✅ | ❌ |
| Filter by NATURE, ministere substring, NOR prefix | ✅ | ❌ |
| Date-range backfill (last ~10 months) | ✅ | ❌ live only |
| **No OAuth, no rate limit, no proxy** | ✅ | varies |
| Success rate (live) | **99%+** | varies |
| Price per article | **$0.005** | unknown |

### What can this JORF scraper do?

- 🇫🇷 **Full JORF coverage** — every decret, loi, arrete, ordonnance, decision, avis, circulaire and deliberation published in the Journal Officiel
- 🗓️ **Date-range search** — pick any window in the last ~10 months (DILA rolling archive)
- ⚖️ **NATURE filter** — restrict to DECRET / LOI / ARRETE / DECISION / etc.
- 🏛️ **Ministere filter** — substring match on `MINISTERE` (e.g. `interieur`, `economie`, `sante`)
- 🔎 **NOR lookup mode** — pass exact NOR codes (12-char identifier) and get back the matching articles
- 📝 **Full structured fields** — NOR, ELI URI, ELI alias, signataires, visas, notice, travaux préparatoires, full body text
- 🔗 **Legifrance URL** included on every record — direct link to the official text
- 🚀 **HTTP-only** — no OAuth, no quota, no proxy, no JavaScript

### What data can you extract per JORF article?

| Field | Description |
|-------|-------------|
| `id` | JORF text ID (e.g. `JORFTEXT000054280280`) |
| `nature` | DECRET / LOI / ARRETE / DECISION / ORDONNANCE / AVIS / DELIBERATION ... |
| `title` | Full title (TITREFULL) |
| `title_short` | Short title (TITRE) |
| `num` | Official number (e.g. `2026-518`) |
| `num_parution` | JORF issue number (e.g. `0143`) |
| `num_sequence` | Sequence within the issue |
| `nor` | NOR code, 12 chars (e.g. `INTD2604081D`) — primary key for compliance teams |
| `date_publi` | Publication date in JORF (YYYY-MM-DD) |
| `date_texte` | Date of the underlying text (when different from publication) |
| `origine` | Always `JORF` for this scraper |
| `ministere` | Issuing ministry (e.g. `Ministère de l'intérieur`) |
| `autorite` | Issuing authority (when set) |
| `id_eli` | Canonical ELI URI (NOR-based) |
| `id_eli_alias` | ELI alias URI (NUM-based) |
| `legifrance_url` | Direct Legifrance URL |
| `visas` | "Vu …" preamble text |
| `notice` | Public-friendly notice (publics concernés, objet, entrée en vigueur) |
| `travaux_preparatoires` | TP/CONTENU section when present |
| `signataires` | Signatories block (Prime Minister, ministers) |
| `body_text` | Full text concatenated article-by-article |
| `body_length` | Character count of `body_text` |
| `source_archive` | Source DILA archive filename (auditability) |
| `scraped_at` | UTC timestamp of extraction |

### How to scrape the Journal Officiel in 5 steps

1. **[Create a free Apify account](https://apify.com/sign-up)** — no credit card required
2. **Open [JORF Scraper](https://apify.com/dltik/jorf-bulletin-officiel-scraper)** on Apify Store
3. **Pick a date range** — e.g. `dateFrom=2026-06-01`, `dateTo=2026-06-20` (max 60 days)
4. **Optional filters** — `natureFilter=["DECRET","LOI"]`, `ministereContains="interieur"`, or `norList=["INTD2604081D"]`
5. **Click Start** — get clean JSON in seconds, exportable to CSV / JSON / Excel from the Apify dataset UI

### How much does it cost to scrape the JORF?

**PAY_PER_EVENT — $0.005 per article extracted** ($5 per 1,000 articles). Failed/empty runs not charged.

| Run size | Articles | Apify cost | Time |
|----------|----------|------------|------|
| Quick test | 10 | $0.05 | ~10s |
| Standard | 100 | $0.50 | ~30s |
| Deep | 500 | $2.50 | ~2min |
| Massive | 5,000 | $25.00 | ~15min |

**Why this price?** Compute + bandwidth per article ≈ $0.0002 → ~95% margin. DILA is free open data; we pass the savings to compliance teams that schedule daily runs at ~150-500 articles/day.

### Input parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `dateFrom` | string (YYYY-MM-DD) | yesterday | Lower bound for `DATE_PUBLI` |
| `dateTo` | string (YYYY-MM-DD) | today | Upper bound for `DATE_PUBLI` (inclusive) |
| `natureFilter` | array of strings | — | e.g. `["DECRET","ARRETE","LOI"]` |
| `ministereContains` | string | — | Substring match (case-insensitive) on `MINISTERE` |
| `norPrefix` | string | — | NOR prefix (e.g. `INTD` for Interieur) |
| `norList` | array of strings | — | Exact NOR codes for lookup mode |
| `includeBodyText` | bool | `true` | Include full `body_text` (set false for metadata-only) |
| `maxResults` | integer | `100` | 1–5000 |
| `proxyConfig` | object | none | DILA is unmetered — proxy rarely needed |

### Output example

```json
{
  "id": "JORFTEXT000054280280",
  "nature": "DECRET",
  "title": "Décret n° 2026-518 du 18 juin 2026 complétant la liste des décisions pouvant donner lieu à une enquête administrative en application de l'article L. 114-1 du code de la sécurité intérieure",
  "title_short": "Décret n°2026-518 du 18 juin 2026",
  "num": "2026-518",
  "num_parution": "0143",
  "num_sequence": "1",
  "nor": "INTD2604081D",
  "date_publi": "2026-06-20",
  "date_texte": "2026-06-18",
  "origine": "JORF",
  "ministere": "Ministère de l'intérieur",
  "autorite": "",
  "id_eli": "https://www.legifrance.gouv.fr/eli/decret/2026/6/18/INTD2604081D/jo/texte",
  "id_eli_alias": "https://www.legifrance.gouv.fr/eli/decret/2026/6/18/2026-518/jo/texte",
  "legifrance_url": "https://www.legifrance.gouv.fr/eli/decret/2026/6/18/INTD2604081D/jo/texte",
  "visas": "Le Premier ministre, Sur le rapport du ministre de l'intérieur, Vu le code de la sécurité intérieure ...",
  "notice": "Publics concernés : professionnels de l'automobile ...",
  "travaux_preparatoires": "",
  "signataires": "Fait le 18 juin 2026. Sébastien Lecornu Par le Premier ministre : Le ministre de l'intérieur, Laurent Nunez ...",
  "body_text": "Article 1: Le code de la sécurité intérieure est modifié ...",
  "body_length": 4321,
  "source_archive": "JORFSIMPLE_20260620-002841.tar.gz",
  "scraped_at": "2026-06-20T08:00:00Z"
}
````

### Use cases

- ⚖️ **Lawtech & compliance** — daily ingestion of every new decret + arrete touching a sector (NOR prefix or ministere substring)
- 🏛️ **Public-affairs monitoring** — track which ministries are publishing what, in real time
- 📚 **Legal-research SaaS** — pre-built dataset of French national law, refreshed daily
- 🔎 **NOR cross-reference** — pull the full text for a list of NOR codes referenced in your case docs
- 🤖 **AI legal assistants** — clean structured corpus to fine-tune or RAG French-law LLMs
- 📊 **Regulatory dashboards** — chart decret/loi publication velocity per ministere over time
- 📰 **Press monitoring** — alert when a new text matching a keyword hits the JORF

### Use the actor via API

**Python:**

```python
import requests

run = requests.post(
    "https://api.apify.com/v2/acts/dltik~jorf-bulletin-officiel-scraper/run-sync-get-dataset-items",
    headers={"Authorization": "Bearer YOUR_APIFY_TOKEN", "Content-Type": "application/json"},
    json={
        "dateFrom": "2026-06-15",
        "dateTo": "2026-06-20",
        "natureFilter": ["DECRET", "ARRETE"],
        "ministereContains": "interieur",
        "includeBodyText": True,
        "maxResults": 200
    },
    timeout=300
).json()
print(f"Scraped {len(run)} JORF articles")
```

**curl:**

```bash
curl -X POST "https://api.apify.com/v2/acts/dltik~jorf-bulletin-officiel-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"dateFrom":"2026-06-15","dateTo":"2026-06-20","natureFilter":["LOI"],"maxResults":50}'
```

### FAQ

**Where does the data come from?**
Directly from **DILA** (Direction de l'Information Légale et Administrative), the official publisher of the JORF. We pull from `https://echanges.dila.gouv.fr/OPENDATA/JORFSIMPLE/` — the canonical open-data feed used by Legifrance itself. No HTML scraping, no anti-bot risk.

**How far back can I scrape?**
DILA's JORFSIMPLE feed keeps a rolling window of approximately the last **10 months** of daily archives. For older articles (going back to 1947), use the **PISTE / Legifrance API** with OAuth2 (free, but requires manual registration at piste.gouv.fr).

**Do I need an API key?**
No. The DILA open-data feed is unauthenticated and unmetered. Just plug Apify input and run.

**What about scheduled runs at midnight?**
DILA publishes the daily JORF archive between **00:00 and 03:00 Paris time**. Runs scheduled in that window may return an empty result for "today" — schedule after **04:00 UTC** for safety.

**What's the difference vs the [Legifrance MCP Server](https://apify.com/dltik/mcp-server-legifrance)?**
The MCP server is for **AI agents** (Claude, GPT) doing tool calls one at a time. This scraper is for **bulk extraction** — give it a date range and get a clean dataset. Complementary, not overlapping.

**Will my IP get banned?**
No reports so far — DILA's open-data servers are unmetered. We've stress-tested at hundreds of archives downloaded per day with no throttle. If you somehow get blocked, flip on the optional datacenter proxy.

***

⭐ **Found this JORF Scraper useful? [Bookmark it](https://apify.com/dltik/jorf-bulletin-officiel-scraper)** — Apify ranks actors by bookmarks, so it's the strongest single signal for Store visibility. One click.

### Other scrapers by dltik

| Actor | What it does | Price |
|-------|-------------|-------|
| [Pappers Sirene Scraper](https://apify.com/dltik/pappers-sirene-scraper) | 26M French companies (SIREN, SIRET, dirigeants, capital) | $0.005/result |
| [BODACC Scraper](https://apify.com/dltik/bodacc-fr-scraper) | French commercial court announcements (faillites, M\&A) | $0.003/record |
| [Legifrance MCP Server](https://apify.com/dltik/mcp-server-legifrance) | French law (codes, jurisprudence, JORF) for AI agents | $0.01/tool-call |
| [Pappers MCP Server](https://apify.com/dltik/mcp-server-pappers) | French companies for AI agents (Claude / GPT) | $0.01/tool-call |
| [BODACC MCP Server](https://apify.com/dltik/mcp-server-bodacc) | BODACC announcements for AI agents | $0.01/tool-call |
| [EUR-Lex Scraper](https://apify.com/dltik/eur-lex-scraper) | EU law (regulations, directives, decisions) | $0.008/doc |
| [HATVP Scraper](https://apify.com/dltik/hatvp-fr-scraper) | French elected officials' financial declarations | varies |
| [BOAMP Scraper](https://apify.com/dltik/boamp-fr-scraper) | French national public procurement tenders | $0.005/tender |
| [France Travail Scraper](https://apify.com/dltik/francetravail-scraper) | 700K+ FR job offers (Pôle Emploi) | $0.0015/job |
| [Annuaire Administration FR](https://apify.com/dltik/annuaire-administration-fr-scraper) | French gov agencies & contacts | $0.003/org |

License: MIT · Author: [dltik](https://apify.com/dltik)

# Actor input Schema

## `dateFrom` (type: `string`):

Lower bound for publication date (DATE\_PUBLI). Format YYYY-MM-DD. Defaults to yesterday if both dates left empty. DILA JORFSIMPLE retains the last ~10 months of daily archives.

## `dateTo` (type: `string`):

Upper bound for publication date (DATE\_PUBLI). Format YYYY-MM-DD inclusive. Defaults to today if left empty. Date range max 60 days per run for performance.

## `natureFilter` (type: `array`):

Restrict to specific JORF natures. Common values: DECRET, ARRETE, LOI, DECISION, DELIBERATION, ORDONNANCE, AVIS, CIRCULAIRE. Leave empty to return all natures.

## `ministereContains` (type: `string`):

Substring match on MINISTERE field. Example: 'interieur', 'economie', 'sante', 'justice'. Leave empty for no filter.

## `norPrefix` (type: `string`):

Filter by NOR code prefix (4 letters identify the issuing ministry/body). Examples: 'INTD' = Interieur Direction, 'JUSD' = Justice, 'ECOI' = Economie. Leave empty for no filter.

## `norList` (type: `array`):

Lookup specific articles by exact NOR code (12 chars, e.g. 'INTD2604081D'). When provided, the actor scans archives in the date range looking for these NORs and ignores natureFilter / ministereContains.

## `includeBodyText` (type: `boolean`):

When true, includes the full BLOC\_TEXTUEL article-by-article concatenation in the body\_text field. Adds ~5-50KB per record. Disable for metadata-only runs.

## `maxResults` (type: `integer`):

Maximum number of JORF articles to extract. Cap = 5000 per run. Start with 50 for testing, scale up once happy.

## `proxyConfig` (type: `object`):

Optional Apify proxy. DILA echanges.dila.gouv.fr is unmetered open data — datacenter proxy or none works fine.

## Actor input object example

```json
{
  "natureFilter": [],
  "norList": [],
  "includeBodyText": true,
  "maxResults": 100,
  "proxyConfig": {
    "useApifyProxy": false
  }
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("dltik/jorf-bulletin-officiel-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("dltik/jorf-bulletin-officiel-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call dltik/jorf-bulletin-officiel-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=dltik/jorf-bulletin-officiel-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "JORF Scraper: French Official Journal API (Legifrance + DILA)",
        "description": "Scrape the Journal Officiel de la République Française (JORF). Get decrets, lois, arretes by date range or NOR. Full text, NATURE, NOR, ELI URI, MINISTERE, SIGNATAIRES, Legifrance URLs. Compliance, lawtech, public-affairs. $0.005/article.",
        "version": "1.0",
        "x-build-id": "zsa9AfXUpIYaGyM3x"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/dltik~jorf-bulletin-officiel-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-dltik-jorf-bulletin-officiel-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/dltik~jorf-bulletin-officiel-scraper/runs": {
            "post": {
                "operationId": "runs-sync-dltik-jorf-bulletin-officiel-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/dltik~jorf-bulletin-officiel-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-dltik-jorf-bulletin-officiel-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "dateFrom": {
                        "title": "Date from (YYYY-MM-DD)",
                        "type": "string",
                        "description": "Lower bound for publication date (DATE_PUBLI). Format YYYY-MM-DD. Defaults to yesterday if both dates left empty. DILA JORFSIMPLE retains the last ~10 months of daily archives."
                    },
                    "dateTo": {
                        "title": "Date to (YYYY-MM-DD)",
                        "type": "string",
                        "description": "Upper bound for publication date (DATE_PUBLI). Format YYYY-MM-DD inclusive. Defaults to today if left empty. Date range max 60 days per run for performance."
                    },
                    "natureFilter": {
                        "title": "Filter by NATURE",
                        "type": "array",
                        "description": "Restrict to specific JORF natures. Common values: DECRET, ARRETE, LOI, DECISION, DELIBERATION, ORDONNANCE, AVIS, CIRCULAIRE. Leave empty to return all natures.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "ministereContains": {
                        "title": "Ministry contains (case-insensitive)",
                        "type": "string",
                        "description": "Substring match on MINISTERE field. Example: 'interieur', 'economie', 'sante', 'justice'. Leave empty for no filter."
                    },
                    "norPrefix": {
                        "title": "NOR code prefix",
                        "type": "string",
                        "description": "Filter by NOR code prefix (4 letters identify the issuing ministry/body). Examples: 'INTD' = Interieur Direction, 'JUSD' = Justice, 'ECOI' = Economie. Leave empty for no filter."
                    },
                    "norList": {
                        "title": "Exact NOR codes (lookup mode)",
                        "type": "array",
                        "description": "Lookup specific articles by exact NOR code (12 chars, e.g. 'INTD2604081D'). When provided, the actor scans archives in the date range looking for these NORs and ignores natureFilter / ministereContains.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "includeBodyText": {
                        "title": "Include full body text",
                        "type": "boolean",
                        "description": "When true, includes the full BLOC_TEXTUEL article-by-article concatenation in the body_text field. Adds ~5-50KB per record. Disable for metadata-only runs.",
                        "default": true
                    },
                    "maxResults": {
                        "title": "Max results",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of JORF articles to extract. Cap = 5000 per run. Start with 50 for testing, scale up once happy.",
                        "default": 100
                    },
                    "proxyConfig": {
                        "title": "Proxy (rarely needed)",
                        "type": "object",
                        "description": "Optional Apify proxy. DILA echanges.dila.gouv.fr is unmetered open data — datacenter proxy or none works fine.",
                        "default": {
                            "useApifyProxy": false
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
