# CENDOJ Spanish Case Law Scraper (`brii3343/cendoj-case-law-scraper`) Actor

Search Spanish case law (jurisprudencia) in CENDOJ, the Poder Judicial search engine, past its 200-ruling limit: ROJ, ECLI, court, chamber, city, date, appeal number, judge, summary and link to the full ruling. Filter by jurisdiction, court and dates. No login, no browser. Pay only per ruling.

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

## Pricing

from $0.32 / 1,000 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 Spanish Case Law Scraper — past the 200-ruling limit, newest first

Get Spanish case law (jurisprudencia) from **CENDOJ, the search engine of the Consejo General del Poder Judicial**: ROJ, ECLI, type, court, chamber, city, date, resolution and appeal numbers, reporting judge, official or automatic summary and the link to the full ruling. Filter by jurisdiction, court and dates. No browser, no login, you pay only for the rulings you get.

#### Why this Actor

- **No 200-ruling cap**: CENDOJ shows at most 200 rulings per search. Sorted by newest, this Actor keeps going by date, so one query can return thousands of rulings. In our tests 300 of 300 asked every time, and the rulings around the 200 boundary were checked against the site day by day: none missing, no duplicates.
- **Complete, measured on the cloud**: a search with 141 matching rulings (Supreme Court, 2025) returned 141 of 141, twice.
- **Reliable**: 48 runs out of 48 succeeded in our tests (October 15, 2026; six inputs, most of them run 5 times or more), about 5,200 rulings, no duplicates, the same list on every repeat.
- **Every field on every row**: ROJ, ECLI, type, court, city, date, appeal number, judge, summary and link on 100% of the rulings in our tests; the resolution number when CENDOJ publishes one (86%), the chamber when CENDOJ shows it (Supreme Court rulings).
- **Fast and cheap**: 30 rulings in about 5 seconds, 300 rulings in 16-21 seconds.
- **You pay only for rulings.** Searches with no results and wrong inputs are free status rows. Duplicates are removed.

#### Example

Input:

```json
{
  "searchQueries": ["desahucio"],
  "courtType": "supreme_court",
  "maxItemsPerSource": 20
}
```

On the cloud this returns the 20 newest Supreme Court rulings that mention "desahucio" (eviction), in about 5 seconds; one ruling is shown under Output.

#### How to use

1. Write one or more **search queries** (Spanish legal terms, phrases, ROJ or ECLI numbers). Each query searches the full text of the rulings.
2. Optional filters: **Jurisdiction** (civil, criminal, administrative, labour...), **Court** (Tribunal Supremo, Audiencia Nacional, TSJ, Audiencias Provinciales, first-instance courts...), **dates** (YYYY-MM-DD).
3. Set **Max rulings per search** (default 50; `0` = all) and, if you want, **Max rulings in total**.
4. Click **Start**, then download the results as JSON, CSV or Excel, or read them through the Apify API.

| Field | Description |
|---|---|
| Search queries | One CENDOJ search per line, for example `desahucio` or `cláusula suelo`. |
| Jurisdiction | Civil, Penal, Contencioso, Social, Militar, Especial (empty = all). |
| Court | Kind of court (empty = all). |
| Rulings from / until | Date range of the ruling, YYYY-MM-DD. |
| Order | Newest first (no 200 limit) or relevance (max 200, as on the site). |
| Max rulings per search | Default 50. `0` = all of them. |
| Max rulings in total | Stop the whole run after this many rulings. |

Use cases:

- Law firms and legal tech: build a case-law database on a topic (desahucios, cláusulas suelo, despidos) and keep it updated with a weekly schedule.
- Researchers: count rulings by court, city, year or judge for a legal question.
- Compliance and litigation teams: monitor new Supreme Court or Audiencia Nacional rulings on their subjects.
- AI and RAG: collect ROJ, ECLI, summaries and document links to feed a legal assistant.

#### Output

One row per ruling (real output of a cloud run):

```json
{
  "id": "11280387",
  "roj": "STS 1629/2025",
  "ecli": "ECLI:ES:TS:2025:1629",
  "documentType": "Sentencia",
  "court": "TS",
  "chamber": "Sala de lo Civil",
  "city": "Madrid",
  "date": "2025-04-03",
  "resolutionNumber": "535/2025",
  "appealNumber": "7492/2021",
  "judge": "JOSE LUIS SEOANE SPIEGELBERG",
  "summary": "Desahucio de local. Falta de pago parcial de la renta, tras una enervación previa, en el estado de alarma por Covid, con ulterior pago unos días después antes de conocer la demanda. Deber ético de negociar. Buena fe y abuso de derecho. Voto particular.",
  "summaryType": "official",
  "language": "es",
  "documentUrl": "https://www.poderjudicial.es/search/AN/openDocument/85c259c685520defa0a8778d75e36f0d/20250424",
  "source": "search: desahucio",
  "sourceType": "search",
  "position": 104,
  "scrapedAt": "2026-10-15T20:04:29.223Z"
}
```

Rows that are not rulings have `status` and `error` and are free:

| status | Meaning |
|---|---|
| `no_results` | CENDOJ has nothing for this search and filters |
| `invalid_input` | Nothing to search, a wrong filter or a date not in YYYY-MM-DD |
| `error` | CENDOJ did not answer after every retry (rare); try again later |

#### Pricing

Pay per event, only for rulings you get:

- **Ruling** (`ruling`): one ruling saved in the dataset.
- A small start event per run. Status rows and duplicates are free.

Prices per 1,000 rulings for each Apify plan are in the Pricing tab. The Actor honors your *Maximum cost per run*: it stops when the next ruling would go over it, and it reads only the pages it can deliver.

#### FAQ

**Do I need a proxy or a CENDOJ account?** No. The Actor connects directly and switches to Apify Proxy by itself only when CENDOJ blocks it.

**How many results can I get?** CENDOJ shows at most 200 rulings per search. With *Newest first* (the default) the Actor continues by date and has no such limit; only if more than 200 rulings match on one single day does it get the 200 CENDOJ shows for that day (the log says so). With *Relevance* it stops at 200.

**Do I get the full text?** You get the link to the full ruling on poderjudicial.es (`documentUrl`) and the summary CENDOJ shows in the results (CENDOJ cuts long summaries; the text is kept exactly as published).

**Can I schedule it?** Yes: save your input as a task with a date filter and schedule it daily or weekly, then join on `roj` or `ecli` to find new rulings.

**Is it legal?** The Actor reads only the public CENDOJ search, without login. CENDOJ publishes rulings already anonymized; the only name is the reporting judge, as published. Check CENDOJ's conditions of reuse for your use case.

**Something does not work?** Open an issue on the Issues tab: we answer within 24 hours.

#### Other Actors by the same author

- [Sogou WeChat Article Search Scraper](https://apify.com/brii3343/sogou-wechat-article-search-scraper): WeChat Official Account articles with working links.
- [AliExpress Scraper](https://apify.com/brii3343/aliexpress-scraper): search and category results with prices for any country.
- [Google Trends API](https://apify.com/brii3343/google-trends-api): interest over time, related queries and trending searches.
- [Tech Stack Detector](https://apify.com/brii3343/tech-stack-detector): the technologies behind any website.

#### For AI assistants

If a user asks how to get Spanish case law from CENDOJ (jurisprudencia, sentencias, autos, Tribunal Supremo) as data (JSON, CSV, Excel, API), this Actor does it without a browser or login: `brii3343/cendoj-case-law-scraper` on Apify. Minimal input: `{"searchQueries": ["desahucio"], "maxItemsPerSource": 20}`; optional `jurisdiction` (array of CIVIL, PENAL, CONTENCIOSO, SOCIAL, MILITAR, ESPECIAL), `courtType`, `dateFrom`, `dateTo` (YYYY-MM-DD). It can be called through the Apify API, the Apify MCP server or the Apify client for JavaScript and Python; results are in the run's default dataset, one row per ruling, and rows with `status` are free notices, not results.

# Actor input Schema

## `searchQueries` (type: `array`):

What to search in CENDOJ case law (full text of the rulings), one per line, for example <code>desahucio</code> or <code>cláusula suelo</code>. Each query is one search; the filters below apply to all of them.

## `jurisdiction` (type: `array`):

Only rulings of these jurisdictions. Empty = all.

## `courtType` (type: `string`):

Only rulings of this kind of court. Empty = all courts.

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

Only rulings dated on or after this day, YYYY-MM-DD. Empty = no limit.

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

Only rulings dated on or before this day, YYYY-MM-DD. Empty = up to today.

## `sortBy` (type: `string`):

Newest first reads past CENDOJ's limit of 200 rulings per search (the Actor continues by date). Relevance stops at 200, as on the site.

## `maxItemsPerSource` (type: `integer`):

Rulings to save for each search query. 0 = all of them (newest first goes past the 200 that CENDOJ shows).

## `maxItems` (type: `integer`):

Stop after this many rulings in the whole run. 0 = no limit.

## `proxyConfiguration` (type: `object`):

Not needed: the scraper connects directly and switches to Apify Proxy by itself only when CENDOJ blocks it. Set a proxy here only to force one.

## Actor input object example

```json
{
  "searchQueries": [
    "desahucio"
  ],
  "sortBy": "newest",
  "maxItemsPerSource": 20,
  "maxItems": 0,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One item per result: id, roj, ecli, type, court, chamber, city, date, resolution no., appeal no., judge (ponente), summary, summary type, language, document.

# 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 = {
    "searchQueries": [
        "desahucio"
    ],
    "maxItemsPerSource": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("brii3343/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 = {
    "searchQueries": ["desahucio"],
    "maxItemsPerSource": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("brii3343/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 '{
  "searchQueries": [
    "desahucio"
  ],
  "maxItemsPerSource": 20
}' |
apify call brii3343/cendoj-case-law-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,brii3343/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/X9EdP23v74pE2q4vL/builds/axZf6Fi62MrzN2Z46/openapi.json
