# CENDOJ Scraper: Spanish Case Law and Jurisprudencia, Full Text (`getascraper/cendoj-case-law-scraper`) Actor

Search Spanish case law from CENDOJ / Poder Judicial (jurisprudencia): sentencias, autos, and acuerdos with real court names, not internal codes. Full judgment text in one run, no second paid run needed, plus Monitor Mode for new rulings. Exports to CSV, JSON, or Excel. From $0.82/1,000 results.

- **URL**: https://apify.com/getascraper/cendoj-case-law-scraper.md
- **Developed by:** [GetAScraper](https://apify.com/getascraper) (community)
- **Categories:** Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.62 / 1,000 case rulings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## 🏛️ CENDOJ Scraper: Spanish Case Law and Jurisprudencia, Full Text

<table width="100%">
<tr>
<td style="padding:24px 28px;background:#EEF2F6;border:1px solid #C7D2DD;border-top:4px solid #1E3A5F;border-radius:12px">
<span style="font-size:23px;font-weight:800;color:#1C1917;line-height:1.3">Search Spanish case law and get the full ruling in one run</span><br>
<span style="font-size:15px;color:#57534E;line-height:1.6">Search sentencias, autos, and acuerdos from CENDOJ (Spain's judicial database) by keyword, court, or exact ROJ/ECLI. Pull the full judgment text in the same run, filter by real court names instead of internal codes, and turn on Monitor Mode to catch only new rulings on a schedule.</span>
</td>
</tr>
</table>

<table width="100%">
<tr>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #C7D2DD;border-radius:10px 0 0 10px;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#14283F">📄 Full text, one run</span><br>
<span style="font-size:12px;color:#57534E">Search and full judgment text together, no second run needed to read what you found</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #C7D2DD;border-left:none;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#14283F">⚖️ Real court names</span><br>
<span style="font-size:12px;color:#57534E">Filter by "Audiencia Provincial" or "Juzgado de lo Mercantil," not a numeric code</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #C7D2DD;border-left:none;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#14283F">🔔 Only what's new</span><br>
<span style="font-size:12px;color:#57534E">Monitor Mode returns just the rulings you haven't seen on your next scheduled run</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #C7D2DD;border-left:none;border-radius:0 10px 10px 0;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#14283F">🔎 Search your way</span><br>
<span style="font-size:12px;color:#57534E">Free text with boolean operators, or an exact ROJ/ECLI lookup, with full filters</span>
</td>
</tr>
</table>

**CENDOJ Scraper** searches the Centro de Documentacion Judicial, the official database of
Spanish court rulings maintained by the Consejo General del Poder Judicial, and returns each
matching sentencia, auto, or acuerdo as a clean, structured row: court, date, ECLI, ROJ, reporting
magistrate, appeal number, and an automatic summary. Run it directly, on a schedule with the
Apify platform, or call it from your own pipeline.

### 🔍 What does CENDOJ Scraper do?

It searches [CENDOJ's public case law database](https://www.poderjudicial.es/search/indexAN.jsp)
by free text (with boolean operators), or by an exact ROJ or ECLI identifier, and returns each
matching ruling with its court, dates, magistrate, appeal number, and an automatic summary. Filter
by jurisdiction, court type, resolution type, autonomous community, and date range. Optionally
pull the complete judgment text in the same run, and optionally track only new rulings across
scheduled runs. No account with CENDOJ is required.

### 💡 Why use CENDOJ Scraper?

- **I need every ruling that mentions a specific clause, from a specific type of court, and I
  need to actually read them,** not just get a list of titles I have to click through one by one.
  Turn on full-text extraction and get the complete judgment alongside the search results.
- **My job is watching for new rulings in one narrow area.** I don't want to re-read the same 40
  cases every week to find the 2 new ones. Monitor Mode remembers what a scheduled search already
  returned and only pushes the new rulings.
- **I'm building a dataset of Spanish case law** and need clean structured fields (court, date,
  ECLI, magistrate) plus the actual judgment text, not a page I have to parse myself.
- **I want to track how a type of case has been decided across regions and courts over time,**
  without first learning CENDOJ's own internal court codes.

### 🚀 How to use CENDOJ Scraper

<table width="100%">
<tr>
<td style="padding:16px 14px;width:33%;background:#EEF2F6;border:1px solid #C7D2DD;border-radius:10px 0 0 10px;vertical-align:top">
<span style="font-size:12px;font-weight:800;color:#1E3A5F;letter-spacing:1px">STEP 1</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Set your filters</span><br>
<span style="font-size:12px;color:#57534E">Enter a search term, or an exact ROJ/ECLI, then narrow by court, jurisdiction, resolution type, region, or date. No code required.</span>
</td>
<td style="padding:16px 14px;width:33%;background:#EEF2F6;border:1px solid #C7D2DD;border-left:none;vertical-align:top">
<span style="font-size:12px;font-weight:800;color:#1E3A5F;letter-spacing:1px">STEP 2</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Run the search</span><br>
<span style="font-size:12px;color:#57534E">The Actor searches CENDOJ and returns each matching ruling as a clean, structured row.</span>
</td>
<td style="padding:16px 14px;width:33%;background:#EEF2F6;border:1px solid #C7D2DD;border-left:none;border-radius:0 10px 10px 0;vertical-align:top">
<span style="font-size:12px;font-weight:800;color:#1E3A5F;letter-spacing:1px">STEP 3</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Get the full picture</span><br>
<span style="font-size:12px;color:#57534E">Turn on full-text extraction to pull the complete ruling, or Monitor Mode to track new ones over time.</span>
</td>
</tr>
</table>

1. Click **Try for free** and open the Input tab.
2. Enter one or more search terms, or an exact ROJ/ECLI to look up one ruling directly.
3. Optionally narrow by jurisdiction, court, resolution type, region, magistrate, or date range.
4. Optionally turn on **Extract Full Judgment Text** or **Monitor Mode**.
5. Click **Start** and download your results as JSON, CSV, Excel, or HTML once the run finishes.

### 📥 Input

| Field | Type | Required | Description |
|---|---|---|---|
| `searchTerms` | array of strings | No | Free-text search terms (up to 4), supports boolean operators. |
| `roj` | string | No | Look up one exact resolution by its ROJ identifier. |
| `ecli` | string | No | Look up one exact resolution by its ECLI identifier. |
| `jurisdictions` | enum (multi) | No | Civil, Penal, Contencioso-Administrativo, Social, Militar, or Especial. |
| `resolutionTypes` | enum (multi) | No | Sentencia, Auto, Acuerdo, and their sub-types. |
| `organoTypes` | enum (multi) | No | Court type, shown by real name (Tribunal Supremo, Audiencia Provincial, etc). |
| `ponente` | string | No | Filter by the reporting magistrate's name. |
| `autonomousCommunities` | enum (multi) | No | Limit to one or more Spanish autonomous communities or cities. |
| `dateFrom` / `dateTo` | date | No | Limit to resolutions within a date range. |
| `sortOrder` | enum | No | Relevance, date, or court name, ascending or descending. |
| `maxResultsPerTerm` | integer | No | Maximum resolutions to fetch per search term (CENDOJ caps every query at 200). |
| `autoExpandBeyond200` | boolean | No | Automatically split a query exceeding 200 results into narrower date ranges. |
| `extractFullText` | boolean | No | Fetch the full judgment text for each result in this same run. |
| `monitorMode` | boolean | No | Only return rulings not seen in a previous run with the same monitor scope. |
| `monitorScope` | string | No | Label that separates the seen-results history of different scheduled monitors. |
| `searchProxyConfiguration` / `fullTextProxyConfiguration` | object | No | Proxy settings. Defaults are already tuned for this site. |

### 📊 Data table

| Field | Type | Description |
|---|---|---|
| `roj` | string | Official Jurisprudence Repository identifier. |
| `ecli` | string | European Case Law Identifier. |
| `court` | string | Court name as shown in the ruling's own title. |
| `resolutionDateIso` | string | Resolution date in YYYY-MM-DD format. |
| `resolutionNumber` | string | Resolution number, when published. |
| `municipality` | string | The issuing court's municipality. |
| `ponente` | string | Reporting magistrate. |
| `appealNumber` | string | Appeal or case number. |
| `summary` | string | CENDOJ's own automatic summary of the ruling. |
| `pdfUrl` / `documentUrl` | string | Link to the official ruling document. |
| `fullText` | string | Complete judgment text, only when full-text extraction is on. |

### 💰 Pricing

This Actor is pay per event. You only pay for the resolutions actually returned, an empty run
costs nothing, and there is no subscription.

- **Case ruling** ($0.82 / 1,000): charged for every resolution returned, in every mode.
- **Full-text extraction** ($1.68 / 1,000): charged only when **Extract Full Judgment Text** is
  on, on top of the base ruling price (about $2.50 / 1,000 total for that mode).

Free-plan runs are limited to a small number of results per run, a few runs per day, and a short
wait between runs, so the Actor stays available and fairly priced for everyone; a paid plan
removes these limits.

### ⭐ Enjoying CENDOJ Scraper?

<table width="100%">
<tr>
<td style="padding:20px 24px 14px;background:#EEF2F6;border:1px solid #C7D2DD;border-left:5px solid #1E3A5F;border-radius:10px 10px 0 0">
<span style="font-size:20px;letter-spacing:4px">⭐ ⭐ ⭐ ⭐ ⭐</span><br>
<span style="font-size:17px;font-weight:800;color:#1C1917">If this Actor saved you a second run, or Monitor Mode is keeping you on top of new rulings, a quick rating helps other legal teams find it.</span><br>
<span style="font-size:14px;color:#57534E">A 5-star rating takes 10 seconds and helps other law firms, compliance teams, and legal-tech builders find it. Your feedback also tells us what to build next.</span>
</td>
</tr>
<tr>
<td style="padding:0;background:#1E3A5F;border:1px solid #C7D2DD;border-top:none;border-radius:0 0 10px 10px;text-align:center">
<a href="https://apify.com/getascraper/cendoj-case-law-scraper/reviews" style="display:block;padding:13px 16px;color:#FFFFFF;text-decoration:none;font-weight:800;font-size:15px;letter-spacing:0.3px">★&nbsp;&nbsp;Rate this Actor on Apify</a>
</td>
</tr>
</table>

### 🛠️ Tips and advanced options

- Start narrow. A specific search term plus a date range returns a manageable, focused result set
  faster than a broad one-word search.
- CENDOJ itself caps any single search at 200 results. If your topic is broad, either narrow your
  filters yourself or turn on **Auto-Expand Beyond 200** to let the Actor split the query into
  narrower date ranges automatically.
- Full-text extraction adds runtime because it fetches each document individually. Turn it on
  only for the results you actually need to read in full.
- For a recurring watch, schedule this Actor with Monitor Mode on and give each schedule its own
  **Monitor Scope** label so different watches don't overwrite each other's history.

### ❓ FAQ

**Do I need a CENDOJ or Poder Judicial account?**
No. This Actor searches CENDOJ's public case law database directly; no login or account is
required.

**Why does full-text extraction take longer than a plain search?**
Getting the complete judgment text means fetching and reading each document individually, on top
of the search itself. It is optional and off by default so a plain search stays fast.

**Can I track new rulings automatically?**
Yes. Turn on Monitor Mode and schedule this Actor on the Apify platform. Each scheduled run will
only return rulings your filters match that weren't returned by a previous run in that same
monitor scope.

**What happens if my search matches more than 200 rulings?**
CENDOJ itself limits any single query to 200 results. Narrow your filters (a date range is the
most effective), or turn on Auto-Expand Beyond 200 to let the Actor split a broad query into
several narrower date-bounded searches automatically.

**Something looks wrong with a result, or you need a custom version of this Actor. What do I do?**
Open the Issues tab on this Actor's Apify Store page. Custom builds and integrations are also
available on request.

### 🔗 Other actors

- [SAM.gov Contract Monitor: Federal Opportunities Scraper](https://apify.com/getascraper/sam-gov-contract-monitor) ↗ - tracks new US federal contract opportunities on a schedule.
- [Wyoming Business Search Scraper: Filings, Agent & Monitor](https://apify.com/getascraper/wyoming-business-registry-scraper) ↗ - searches Wyoming business registry filings and registered agents.
- [SEC EDGAR Scraper for RAG: 10-K/10-Q/8-K as JSON](https://apify.com/getascraper/sec-edgar-rag-extractor) ↗ - extracts SEC filings as clean, structured JSON for RAG pipelines.

# Changelog

This Actor's version history is a separate document: https://apify.com/getascraper/cendoj-case-law-scraper/changelog.md

# Actor input Schema

## `searchTerms` (type: `array`):

Free-text terms to search for in Spanish case law (sentencias, autos, acuerdos). Up to 4 terms per run, each run as a separate query. Supports boolean operators (AND, OR, NOT, NEARn).

## `roj` (type: `string`):

Look up one exact resolution by its official Jurisprudence Repository identifier (ROJ), e.g. "STS 3709/2026". Leave blank for a general search.

## `ecli` (type: `string`):

Look up one exact resolution by its European Case Law Identifier (ECLI), e.g. "ECLI:ES:TS:2026:3709". Leave blank for a general search.

## `jurisdictions` (type: `array`):

Limit results to one or more judicial branches. Leave empty to search all jurisdictions.

## `resolutionTypes` (type: `array`):

Limit results to one or more resolution types (judgment, order, agreement). Leave empty to include all types.

## `organoTypes` (type: `array`):

Limit results to one or more court types. The dropdown shows real court names, not the raw numeric codes CENDOJ uses internally (its own search form and the main incumbent actor both expose those bare codes and expect you to know what they mean). Leave empty to search all courts.

## `ponente` (type: `string`):

Filter by the name of the reporting magistrate (ponente). Leave blank to search all.

## `autonomousCommunities` (type: `array`):

Limit results to one or more Spanish autonomous communities or autonomous cities. This filter is best-effort: CENDOJ's own search form builds this list client-side with JavaScript, so the exact server-side encoding could not be fully confirmed against a live request. Leave empty to search all of Spain if you hit unreliable filtering.

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

Only include resolutions dated on or after this date.

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

Only include resolutions dated on or before this date.

## `sortOrder` (type: `string`):

How to order results within each search term.

## `searchProxyConfiguration` (type: `object`):

Proxy used for search queries when "Extract Full Judgment Text" is off (the default). Datacenter proxy is sufficient here: verified live, CENDOJ's search endpoint returns normal results over plain Apify datacenter proxy with no residential IP needed. Ignored when full-text extraction is on, see the note on that field below.

## `extractFullText` (type: `boolean`):

Fetch and extract the full PDF text of each matched resolution in this same run. Off by default because it is a slower, costlier step that requires a residential Spanish proxy (see below). The main incumbent actor for this niche cannot do this in one run at all, it requires starting a second, separate run with the PDF URLs as input.

## `fullTextProxyConfiguration` (type: `object`):

Proxy used for the ENTIRE run, search included, when "Extract Full Judgment Text" is on (it replaces the search proxy above for that run). This must stay Residential with country Spain (ES): verified live that CENDOJ routes datacenter-proxy requests for the document/PDF endpoint through a CAPTCHA challenge, while Spanish residential IPs are not challenged, and that the document reference is bound to the same session that ran the search, so search and document fetch cannot use two different proxy sessions. This Actor never attempts to solve a CAPTCHA; it only avoids triggering one by using a proxy tier and session the source site treats as one continuous normal visitor.

## `maxResultsPerTerm` (type: `integer`):

Maximum resolutions to fetch per search term. CENDOJ itself hard-caps every single query at 200 results total and silently ignores any further pagination beyond that, verified live, so this is not our own limit. Kept low by default so a default run finishes in minutes.

## `autoExpandBeyond200` (type: `boolean`):

When a query would return more than CENDOJ's 200-result ceiling, automatically re-run it as several narrower date-range sub-queries to recover more of the true result set. Off by default: it issues extra requests, so it adds runtime and cost. The incumbent actor does not offer this at all, it just tells you to narrow your own filters manually.

## `monitorMode` (type: `boolean`):

When on, this Actor remembers which ROJ identifiers it already returned for this exact search configuration and only pushes resolutions it has not seen before. Intended for scheduled, recurring runs (e.g. a daily or weekly watch for new case law matching your filters). The incumbent actor has no equivalent; every run re-returns the full result set from scratch.

## `monitorScope` (type: `string`):

Only used when Monitor Mode is on. A short label that namespaces this schedule's seen-results state, so you can run several different scheduled monitors (e.g. one per client or topic) without them overwriting each other's history. Reuse the same label across runs of the same schedule.

## Actor input object example

```json
{
  "searchTerms": [
    "divorcio"
  ],
  "roj": "",
  "ecli": "",
  "jurisdictions": [],
  "resolutionTypes": [],
  "organoTypes": [],
  "ponente": "",
  "autonomousCommunities": [],
  "sortOrder": "RELEVANCE",
  "searchProxyConfiguration": {
    "useApifyProxy": true
  },
  "extractFullText": false,
  "fullTextProxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "ES"
  },
  "maxResultsPerTerm": 25,
  "autoExpandBeyond200": false,
  "monitorMode": false,
  "monitorScope": "default"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "searchTerms": [
        "divorcio"
    ],
    "roj": "",
    "ecli": "",
    "jurisdictions": [],
    "resolutionTypes": [],
    "organoTypes": [],
    "ponente": "",
    "autonomousCommunities": [],
    "sortOrder": "RELEVANCE",
    "searchProxyConfiguration": {
        "useApifyProxy": true
    },
    "extractFullText": false,
    "fullTextProxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "ES"
    },
    "maxResultsPerTerm": 25,
    "autoExpandBeyond200": false,
    "monitorMode": false,
    "monitorScope": "default"
};

// Run the Actor and wait for it to finish
const run = await client.actor("getascraper/cendoj-case-law-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 = {
    "searchTerms": ["divorcio"],
    "roj": "",
    "ecli": "",
    "jurisdictions": [],
    "resolutionTypes": [],
    "organoTypes": [],
    "ponente": "",
    "autonomousCommunities": [],
    "sortOrder": "RELEVANCE",
    "searchProxyConfiguration": { "useApifyProxy": True },
    "extractFullText": False,
    "fullTextProxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "ES",
    },
    "maxResultsPerTerm": 25,
    "autoExpandBeyond200": False,
    "monitorMode": False,
    "monitorScope": "default",
}

# Run the Actor and wait for it to finish
run = client.actor("getascraper/cendoj-case-law-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "divorcio"
  ],
  "roj": "",
  "ecli": "",
  "jurisdictions": [],
  "resolutionTypes": [],
  "organoTypes": [],
  "ponente": "",
  "autonomousCommunities": [],
  "sortOrder": "RELEVANCE",
  "searchProxyConfiguration": {
    "useApifyProxy": true
  },
  "extractFullText": false,
  "fullTextProxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "ES"
  },
  "maxResultsPerTerm": 25,
  "autoExpandBeyond200": false,
  "monitorMode": false,
  "monitorScope": "default"
}' |
apify call getascraper/cendoj-case-law-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,getascraper/cendoj-case-law-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/1cnOuHQ780KUmEHOe/builds/uQaMS8JnbHMd2esnI/openapi.json
