# Cendoj (`legaltech/cendoj`) Actor

Automatiza la búsqueda de jurisprudencia en el CENDOJ. Permite buscar sentencias, autos y acuerdos por término de texto y filtrarlos por jurisdicción, tipo de órgano, tipo de resolución, comunidad autónoma y rango de fechas.

- **URL**: https://apify.com/legaltech/cendoj.md
- **Developed by:** [Miguel González](https://apify.com/legaltech) (community)
- **Categories:** Automation
- **Stats:** 4 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## 🏛️ Cendoj - Buscador de sentencias

Actor de [Apify](https://apify.com) que automatiza la búsqueda de jurisprudencia en el **CENDOJ** (Centro de Documentación Judicial del Consejo General del Poder Judicial). Permite buscar sentencias, autos y acuerdos por término de texto y filtrarlos por jurisdicción, tipo de órgano, tipo de resolución, comunidad autónoma y rango de fechas.

Para cada resolución encontrada, el actor extrae sus metadatos (ECLI, ROJ, ponente, municipio, número de recurso, etc.), un resumen automático y la URL del PDF oficial. Además, en una segunda ejecución puedes pedirle que **descargue y extraiga el texto completo** de sentencias concretas (campo `pdfUrls`) para analizarlas.

### ✨ Características

- 🔎 Búsqueda por múltiples términos en una sola ejecución (hasta 200).
- � Operadores booleanos en el término de búsqueda (`Y`, `O`, `NO`, `PROXn`).
- 🧰 Filtros avanzados: jurisdicción, tipo de órgano, tipo de resolución, comunidad autónoma y fechas.
- ↕️ Ordenación de resultados (relevancia, fecha, órgano).
- 📄 Extracción de metadatos completos (ECLI, ROJ, ponente, municipio, número de resolución y recurso).
- 📝 Resumen automático de cada sentencia.
- 🔗 URL de descarga del PDF oficial de cada resolución.
- 📑 Extracción bajo demanda del **texto completo** de sentencias concretas (campo `pdfUrls`).

### 📥 Entrada (Input)

La entrada se define mediante un objeto JSON. Debes indicar **al menos uno** de estos dos campos: `searchTerms` (para buscar jurisprudencia) o `pdfUrls` (para extraer el texto de sentencias concretas).

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `searchTerms` | `array<string>` | ✅ Uno de los dos | Lista de términos a buscar en la jurisprudencia (máx. 50). Admite [operadores booleanos](#-operadores-de-búsqueda). |
| `pdfUrls` | `array<string>` | ✅ Uno de los dos | Lista de URLs de PDF (campo `pdfUrl` de resultados anteriores) de las que extraer el **texto completo** (máx. 50). Úselo en una segunda ejecución tras una búsqueda. Ver [Extracción de texto](#-extracción-de-texto-de-sentencias-concretas). |
| `jurisdictions` | `array<string>` | No | Jurisdicciones: `CIVIL`, `PENAL`, `CONTENCIOSO`, `SOCIAL`, `MILITAR`, `ESPECIAL`. Por defecto, todas. |
| `organoTypes` | `array<string>` | No | Tipos de órgano judicial (Tribunal Supremo, Audiencia Nacional, Audiencia Provincial, etc.). Por defecto, todos. |
| `resolutionTypes` | `array<string>` | No | Tipos de resolución: `SENTENCIA`, `AUTO`, `ACUERDO`. Por defecto, todos. |
| `locations` | `array<string>` | No | Comunidades autónomas (ej. `MADRID`, `CATALUÑA`). Por defecto, todas. *Solo aplica en la vía HTTP.* |
| `dateFrom` | `string` | No | Fecha de resolución inicial (`YYYY-MM-DD` o `DD/MM/YYYY`). |
| `dateTo` | `string` | No | Fecha de resolución final (`YYYY-MM-DD` o `DD/MM/YYYY`). |
| `sortOrder` | `string` | No | Criterio de ordenación: `Relevance` (coincidencia, por defecto), `IN_FECHARESOLUCION:increasing` (fecha asc.), `IN_FECHARESOLUCION:decreasing` (fecha desc.), `IN_FECHAENTRADA:numberdecreasing` (lo más nuevo), `IP_TIPOORGANO:alphabetical` (órgano a–z), `IP_TIPOORGANO:reversealphabetical` (órgano z–a). |
| `maxResults` | `integer` | No | Máximo de sentencias por término (1–200). Por defecto, `10`. |
| `proxyConfiguration` | `object` | No | Configuración de proxy. Por defecto, proxy residencial de España. |


### 🧮 Operadores de búsqueda

El campo `searchTerms` admite **operadores booleanos** para construir consultas precisas. Puedes escribirlos tanto en su sintaxis nativa de CENDOJ (español) como en la estándar en inglés: el actor traduce automáticamente la versión en inglés a la que entiende el buscador.

| Operador (escribe) | Equivalente CENDOJ | Significado | Ejemplo |
| --- | --- | --- | --- |
| `AND` | `Y` | Ambos términos deben aparecer. | `abogacía AND responsabilidad` |
| `OR` | `O` | Basta con que aparezca uno de los términos. | `"Real Decreto 135/2021" OR "Real Decreto 658/2001"` |
| `NOT` | `NO` | Excluye las resoluciones con ese término. | `costas NOT "Ley 22/1988"` |
| `NEARn` | `PROXn` | Los términos están a menos de `n` palabras de distancia. | `estatuto NEAR5 abogacía` |

Notas:

- Los operadores deben escribirse en **MAYÚSCULAS** como palabra completa; los términos en minúsculas se tratan como texto literal.
- Puedes usar **comillas** para frases exactas: `"condena en costas"`.
- Si escribes directamente los operadores en español (`Y`, `O`, `NO`, `PROX20`), se envían tal cual.
- **Exclusión de frases con `NOT`/`NO`:** el buscador de CENDOJ solo excluye la **palabra inmediatamente siguiente** al operador. Por eso, para excluir una frase de varias palabras, **enciérrala entre comillas**: el actor la expande automáticamente a una exclusión por cada palabra (por ejemplo, `NOT "defectos constructivos"` se envía como `NO defectos NO constructivos`). Las palabras vacías (`de`, `la`, `el`...) se omiten para no vaciar los resultados.

#### 🤖 Uso con Claude Code / MCP de Apify (lenguaje natural)

Este actor está pensado para integrarse en **Claude Code** a través del **MCP de Apify**. La idea es que el usuario describa su necesidad en lenguaje natural y el asistente **construya automáticamente** el valor de `searchTerms` con los operadores adecuados, sin que el usuario tenga que conocerlos.

> 📖 Guía de integración: [Cómo enlazar Claude Code con Apify (MCP)](https://www.legaltechnologybootcamp.com/es/blog/claude-code-apify-mcp-registro-propiedad/).

Directrices para que el asistente (LLM) genere la query:

- Cuando el usuario quiera **varias alternativas equivalentes** (sinónimos, varias normas, varios nombres), únelas con `OR`.
- Cuando el usuario exija que aparezcan **varios conceptos a la vez**, únelos con `AND`.
- Cuando el usuario quiera **descartar ruido** (un tema, una ley o un sentido no deseado), usa `NOT`. Si lo que se excluye es una **frase de varias palabras**, ponla **entre comillas** (`NOT "defectos constructivos"`) para que el actor la expanda correctamente; de lo contrario CENDOJ solo excluiría la primera palabra.
- Cuando dos conceptos deban referirse **a lo mismo** (estar próximos en el texto), usa `NEARn` (por defecto `NEAR5`–`NEAR10`).
- Encierra entre **comillas** las expresiones de varias palabras que deban buscarse literalmente.

Ejemplos de traducción de lenguaje natural a query:

| El usuario pide... | `searchTerms` generado |
| --- | --- |
| "Sentencias sobre gastos hipotecarios pero que no traten de temas penales" | `"gastos hipotecarios" NOT penal` |
| "Obra nueva, pero excluyendo defectos constructivos y derecho de superficie" | `"obra nueva" NOT "defectos constructivos" NOT "derecho de superficie"` |
| "Casos del Real Decreto 135/2021 o del 658/2001" | `"Real Decreto 135/2021" OR "Real Decreto 658/2001"` |
| "Resoluciones sobre responsabilidad del abogado en relación con las costas" | `abogado AND costas` |
| "Que hablen del estatuto de la abogacía, no del de los trabajadores" | `estatuto NEAR5 abogacía` |

#### 🗂️ Mapeo de filtros desde lenguaje natural

Además del término de búsqueda, el asistente debe rellenar automáticamente los filtros estructurados cuando el usuario los menciona en lenguaje natural:

- **Jurisdicción** (`jurisdictions`): "civil" → `CIVIL`, "penal" → `PENAL`, "contencioso" / "contencioso-administrativo" → `CONTENCIOSO`, "social" / "laboral" → `SOCIAL`, "militar" → `MILITAR`, "especial" → `ESPECIAL`.
- **Tipo de resolución** (`resolutionTypes`): "sentencias" → `SENTENCIA`, "autos" → `AUTO`, "acuerdos" → `ACUERDO`.
- **Tipo de órgano** (`organoTypes`): ⚠️ **los códigos son opacos y NO siguen el orden alfabético; NO los adivines, cópialos de la tabla de abajo.** Errores típicos: usar `12` (Sala Penal) para asuntos civiles, o `31` (TSJ) creyendo que es el Juzgado de Primera Instancia (que es `42`). Consulta la [tabla de referencia de órganos](#-tabla-de-referencia-organotypes).
- **Comunidad autónoma** (`locations`): "Madrid" → `MADRID`, "Cataluña" → `CATALUÑA`, "Andalucía" → `ANDALUCÍA`, etc. *(solo aplica en la vía HTTP).*
- **Fechas** (`dateFrom` / `dateTo`): "desde 2020" → `dateFrom: "2020-01-01"`, "el último año", "entre enero y marzo de 2024", etc. Formato `YYYY-MM-DD`.
- **Ordenación** (`sortOrder`): "las más recientes" → `IN_FECHARESOLUCION:decreasing`, "las más antiguas" → `IN_FECHARESOLUCION:increasing`, "las más relevantes" → `Relevance` (por defecto).
- **Número de resultados** (`maxResults`): por defecto `10`. Súbelo (hasta `200`) cuando el usuario pida "todas", "un listado amplio", "un análisis exhaustivo" o similar.
- **Texto completo** (`pdfUrls`): cuando el usuario pida "descarga/analiza el texto de estas sentencias" tras una búsqueda, relanza el actor pasando en `pdfUrls` los `pdfUrl` de las sentencias elegidas (ver [Extracción de texto](#-extracción-de-texto-de-sentencias-concretas)). No uses `fetch` ni otros actores para bajar el PDF.

> 💡 Para construir **tablas**, los campos más útiles de la salida son `organo`, `jurisdiction`, `resolutionDateISO`, `roj`, `ecli`, `title`, `ponente`, `summary` y `pdfUrl`.

#### 🏛️ Tabla de referencia (`organoTypes`)

Mapea el órgano que pide el usuario a su **código exacto** de esta tabla (son los valores oficiales del `<select>` de CENDOJ). Para órganos con varias salas, usa el **código combinado** (primera fila de cada grupo) salvo que el usuario precise una sala concreta.

| Código (`organoTypes`) | Órgano (título oficial) |
| --- | --- |
| `11\|12\|13\|14\|15\|16` | **Tribunal Supremo** (todas las salas) |
| `11` | Tribunal Supremo. Sala de lo Civil |
| `12` | Tribunal Supremo. Sala de lo Penal |
| `13` | Tribunal Supremo. Sala de lo Contencioso |
| `14` | Tribunal Supremo. Sala de lo Social |
| `15` | Tribunal Supremo. Sala de lo Militar |
| `16` | Tribunal Supremo. Sala de lo Especial |
| `22\|2264\|23\|24\|25\|26\|27\|28\|29` | **Audiencia Nacional** (todas las salas) |
| `22` | Audiencia Nacional. Sala de lo Penal |
| `2264` | Sala de Apelación de la Audiencia Nacional |
| `23` | Audiencia Nacional. Sala de lo Contencioso |
| `24` | Audiencia Nacional. Sala de lo Social |
| `27` | Audiencia Nacional. Juzgados Centrales de Instrucción / Tribunal Central Instancia Sec. Instr. |
| `26` | Audiencia Nacional. Juzgado Central de Menores |
| `25` | Audiencia Nacional. Juzgado Central de Vigilancia Penitenciaria |
| `29` | Audiencia Nacional. Juzgados Centrales de lo Contencioso / Tribunal Central Instancia Sec. Contencioso |
| `28` | Audiencia Nacional. Juzgados Centrales de lo Penal |
| `31\|31201202\|33\|34` | **Tribunal Superior de Justicia** (todas las salas) |
| `31` | Tribunal Superior de Justicia. Sala de lo Civil y Penal |
| `31201202` | Sección de Apelación Penal. TSJ Sala de lo Civil y Penal |
| `33` | Tribunal Superior de Justicia. Sala de lo Contencioso |
| `34` | Tribunal Superior de Justicia. Sala de lo Social |
| `37` | **Audiencia Provincial** |
| `38` | Audiencia Provincial. Tribunal Jurado |
| `1001` | Tribunal de Marca de la UE |
| `42` | **Juzgado de Primera Instancia** / Tribunal Instancia Sec. Civil |
| `43` | Juzgado de Instrucción |
| `45` | Juzgado de lo Contencioso Administrativo / Tribunal Instancia Sec. Contencioso-Administrativo |
| `53` | Juzgado de Menores / Tribunal Instancia Sec. Menores |
| `41` | Juzgado de 1ª Inst. Instr. / Tribunal Instancia Sec. Civil Instr. |
| `47` | Juzgado de lo Mercantil / Tribunal Instancia Sec. Mercantil |
| `1002` | Juzgados de Marca de la UE |
| `51` | Juzgado de lo Penal / Tribunal Instancia Sec. Penal |
| `44` | Juzgado de lo Social / Tribunal Instancia Sec. Social |
| `52` | Juzgado de Vigilancia Penitenciaria / Tribunal Instancia Sec. Vigilancia Penitenciaria |
| `48` | Juzgado de Violencia sobre la Mujer |
| `83` | Tribunal Militar Territorial |
| `85` | Tribunal Militar Central |
| `75` | Consejo Supremo de Justicia Militar |
| `36` | Audiencia Territorial |

> ⚠️ **"Juzgado de Primera Instancia" = `42`**, **NO** `31` (que es el Tribunal Superior de Justicia). **"Sala de lo Civil del Supremo" = `11`**, **NO** `12` (que es Penal). **"Audiencia Provincial" = `37`**, **NO** `42`. Verifica siempre el código contra esta tabla antes de llamar al actor.



### 📤 Salida (Output)

Los resultados se almacenan en el **dataset** del actor. Cada elemento corresponde a una resolución con la siguiente estructura:

```json
{
    "searchTerm": "Gastos hipotecarios",
    "title": "ATIM Madrid, a 10 de junio de 2026 - ROJ: ATIM M 31/2026",
    "roj": "ATIM M 31/2026",
    "reference": "11755479",
    "ecli": "ECLI:ES:TIM:2026:31A",
    "jurisdiction": "Civil",
    "organo": "Tribunal de Instancia Mercantil",
    "resolutionDate": "20260610",
    "resolutionDateISO": "2026-06-10",
    "resolutionNumber": null,
    "municipality": "Madrid",
    "ponente": "NOMBRE_PONENTE",
    "appealNumber": "573/2025",
    "summary": "Resumen automático de la resolución...",
    "pdfUrl": "https://www.poderjudicial.es/search/contenidos.action?action=contentpdf&databasematch=AN&reference=11755479&optimize=20260612&publicinterface=true&tab=AN",
}
````

| Campo | Descripción |
| --- | --- |
| `searchTerm` | Término de búsqueda que originó el resultado. |
| `title` | Título de la resolución. |
| `roj` | Repositorio Oficial de Jurisprudencia (identificador ROJ). |
| `reference` | Referencia interna del documento en CENDOJ. |
| `ecli` | Identificador europeo de jurisprudencia (ECLI). |
| `jurisdiction` | Jurisdicción de la búsqueda en formato legible (p. ej. `Civil`). `null` si no se filtró por jurisdicción. |
| `organo` | Órgano judicial legible derivado del ROJ (p. ej. `Tribunal Supremo`, `Audiencia Provincial`). |
| `resolutionDate` | Fecha de resolución (formato `YYYYMMDD`). |
| `resolutionDateISO` | Fecha de resolución en formato legible `YYYY-MM-DD`. |
| `resolutionNumber` | Número de resolución (si está disponible). |
| `municipality` | Municipio del órgano judicial. |
| `ponente` | Magistrado ponente. |
| `appealNumber` | Número de recurso. |
| `summary` | Resumen automático generado por el buscador. |
| `pdfUrl` | URL de descarga del PDF oficial (es también el documento online: el visor de CENDOJ muestra ese mismo PDF). |

### � Extracción de texto de sentencias concretas

El buscador devuelve metadatos y resumen, pero **no** el texto completo de los PDFs (descargarlos todos sería lento y CENDOJ bloquea las descargas masivas). Para analizar el contenido de sentencias concretas, sigue un flujo en **dos pasos**:

1. **Busca** con `searchTerms` y revisa los resultados. Cada uno incluye su `pdfUrl`.
2. **Vuelve a ejecutar** el actor pasando en `pdfUrls` las URLs (`pdfUrl`) de las sentencias que te interesen. El actor descargará esos PDFs y extraerá su texto.

Cuando usas `pdfUrls`, **no es necesario** rellenar `searchTerms`. La salida de esta segunda ejecución tiene esta forma:

```json
{
    "pdfUrl": "https://www.poderjudicial.es/search/contenidos.action?action=contentpdf&databasematch=TS&reference=11753648&...",
    "reference": "11753648",
    "databasematch": "TS",
    "text": "Texto completo de la sentencia extraído del PDF..."
}
```

| Campo | Descripción |
| --- | --- |
| `pdfUrl` | URL del PDF procesado (la que pasaste en `pdfUrls`). |
| `reference` | Referencia interna del documento (extraída de la URL). |
| `databasematch` | Base de datos de origen (extraída de la URL). |
| `text` | Texto completo de la sentencia. Es `null` (con campo `error`) si no se pudo extraer. |

> ⚠️ **Por qué no se descarga directamente el PDF:** CENDOJ protege las URLs de PDF con un control anti-descargas masivas (CAPTCHA "Control Descargas masivas") que bloquea las peticiones sin una sesión de navegador válida. Por eso una descarga directa con `fetch`/`curl` o con actores genéricos falla. Este actor abre una sesión real (cookies + aviso legal + proxy residencial de España) y descarga el PDF desde dentro de esa sesión, por lo que **es la vía fiable** para obtener el texto.
>
> 💡 Límite de **50 PDFs por ejecución** para no disparar el bloqueo. Si necesitas más, divídelos en varias ejecuciones.

#### 🤖 Uso con Claude Code / MCP

El flujo encaja de forma natural con el MCP: primero el asistente lanza la búsqueda, muestra los resultados y, cuando le pides "descárgame el texto de estas dos sentencias para analizarlas", relanza el actor con el campo `pdfUrls` rellenado con los `pdfUrl` correspondientes del paso anterior. **No uses `fetch` ni otros actores** para bajar el PDF: usa este mismo actor con `pdfUrls`.

> 📝 También existe la variable de entorno `EXTRACT_PDF_TEXT=true`, que extrae el texto de **todas** las sentencias durante la propia búsqueda. Es útil para procesos batch, pero más lento; para análisis puntuales se recomienda el campo `pdfUrls`.

### �📝 Notas

- El número máximo de resultados por término es **200** por ejecución.

# Actor input Schema

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

Lista de términos a buscar en la jurisprudencia de CENDOJ. Admite operadores booleanos en el propio término: Y/AND (ambos), O/OR (cualquiera), NO/NOT (excluir) y PROXn/NEARn (proximidad, ej. PROX20). Ejemplo: "abogado Y costas O "condena en costas" NO penal".

## `pdfUrls` (type: `array`):

Lista de URLs de PDF (campo `pdfUrl` de resultados anteriores) de las que quieres descargar y extraer el texto completo para analizarlas. Úsalo en una segunda ejecución tras una búsqueda: copia aquí las URLs de las sentencias que te interesen. Si rellenas este campo, el actor solo extrae el texto de esas sentencias (no es necesario rellenar 'Términos de Búsqueda'). Límite de 50 por ejecución para evitar bloqueos por descargas masivas.

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

Selecciona una o más jurisdicciones. Si no se selecciona ninguna, se buscará en todas por defecto.

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

Tipo de órgano judicial. Los códigos son opacos: NO los adivines, lee el título (enumTitle) de cada opción y elige el que coincide exactamente con lo que pide el usuario. Para un órgano con varias salas (Tribunal Supremo, Audiencia Nacional, TSJ) usa el código combinado salvo que se precise una sala. Errores frecuentes a evitar: 'Juzgado de Primera Instancia' es el código 42 (NO 31, que es el Tribunal Superior de Justicia); la 'Sala de lo Civil del Tribunal Supremo' es 11 (NO 12, que es Penal); la 'Audiencia Provincial' es 37 (NO 42). Si no se indica ninguno, se busca en todos.

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

Selecciona uno o más tipos de resolución. Si no se selecciona ninguno, se buscará en todos.

## `locations` (type: `array`):

Selecciona una o más Comunidades Autónomas. Si no se selecciona ninguna, se buscará en todas.

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

Define el número máximo de sentencias a extraer por cada término de búsqueda. Se pagina automáticamente de 50 en 50. El límite es 200 por ejecución.

## `paragraphs` (type: `integer`):

Si es mayor que 0, al extraer el texto de un PDF se devuelven solo ese número de PÁRRAFOS relevantes (los pasajes donde aparecen los términos buscados, en frases completas y priorizando los Fundamentos de Derecho) en lugar del texto íntegro. Ideal para análisis con un LLM (menos tokens). Aplica cuando se extrae texto (campo `pdfUrls`, o búsqueda con extracción de texto activada). 0 = texto completo.

## `paragraphTerms` (type: `string`):

Términos con los que localizar los pasajes en el modo párrafos. Si se deja vacío, se usa el propio término de búsqueda (en la vía `searchTerms`). Es recomendable rellenarlo cuando se usa `pdfUrls` (segunda ejecución), ya que ahí no hay término de búsqueda.

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

Fecha de resolución inicial (opcional). Se incluyen las sentencias dictadas a partir de esta fecha.

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

Fecha de resolución final (opcional). Se incluyen las sentencias dictadas hasta esta fecha.

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

Criterio de ordenación de los resultados. Por defecto se ordena por coincidencia (relevancia).

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

Configuración de proxy. CENDOJ bloquea las IP de datacenter, por lo que se recomienda usar proxy residencial de España (grupo RESIDENTIAL, país ES). El tráfico residencial se factura por GB consumido.

## Actor input object example

```json
{
  "searchTerms": [
    "Gastos hipotecarios"
  ],
  "pdfUrls": [],
  "jurisdictions": [],
  "organoTypes": [],
  "resolutionTypes": [],
  "locations": [],
  "maxResults": 10,
  "paragraphs": 0,
  "sortOrder": "Relevance",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "ES"
  }
}
```

# Actor output Schema

## `overview` (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": [
        "Gastos hipotecarios"
    ],
    "pdfUrls": [],
    "jurisdictions": [],
    "organoTypes": [],
    "resolutionTypes": [],
    "locations": [],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "ES"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("legaltech/cendoj").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": ["Gastos hipotecarios"],
    "pdfUrls": [],
    "jurisdictions": [],
    "organoTypes": [],
    "resolutionTypes": [],
    "locations": [],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "ES",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("legaltech/cendoj").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 '{
  "searchTerms": [
    "Gastos hipotecarios"
  ],
  "pdfUrls": [],
  "jurisdictions": [],
  "organoTypes": [],
  "resolutionTypes": [],
  "locations": [],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "ES"
  }
}' |
apify call legaltech/cendoj --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Cendoj",
        "description": "Automatiza la búsqueda de jurisprudencia en el CENDOJ. Permite buscar sentencias, autos y acuerdos por término de texto y filtrarlos por jurisdicción, tipo de órgano, tipo de resolución, comunidad autónoma y rango de fechas.",
        "version": "2.0",
        "x-build-id": "XqyvagijlyTjZYUdG"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/legaltech~cendoj/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-legaltech-cendoj",
                "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/legaltech~cendoj/runs": {
            "post": {
                "operationId": "runs-sync-legaltech-cendoj",
                "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/legaltech~cendoj/run-sync": {
            "post": {
                "operationId": "run-sync-legaltech-cendoj",
                "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": {
                    "searchTerms": {
                        "title": "Términos de Búsqueda",
                        "maxItems": 50,
                        "type": "array",
                        "description": "Lista de términos a buscar en la jurisprudencia de CENDOJ. Admite operadores booleanos en el propio término: Y/AND (ambos), O/OR (cualquiera), NO/NOT (excluir) y PROXn/NEARn (proximidad, ej. PROX20). Ejemplo: \"abogado Y costas O \\\"condena en costas\\\" NO penal\".",
                        "items": {
                            "type": "string"
                        }
                    },
                    "pdfUrls": {
                        "title": "Descargar texto de sentencias concretas",
                        "maxItems": 50,
                        "type": "array",
                        "description": "Lista de URLs de PDF (campo `pdfUrl` de resultados anteriores) de las que quieres descargar y extraer el texto completo para analizarlas. Úsalo en una segunda ejecución tras una búsqueda: copia aquí las URLs de las sentencias que te interesen. Si rellenas este campo, el actor solo extrae el texto de esas sentencias (no es necesario rellenar 'Términos de Búsqueda'). Límite de 50 por ejecución para evitar bloqueos por descargas masivas.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "jurisdictions": {
                        "title": "Jurisdicciones",
                        "type": "array",
                        "description": "Selecciona una o más jurisdicciones. Si no se selecciona ninguna, se buscará en todas por defecto.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "CIVIL",
                                "PENAL",
                                "CONTENCIOSO",
                                "SOCIAL",
                                "MILITAR",
                                "ESPECIAL"
                            ],
                            "enumTitles": [
                                "Civil",
                                "Penal",
                                "Contencioso",
                                "Social",
                                "Militar",
                                "Especial"
                            ]
                        }
                    },
                    "organoTypes": {
                        "title": "Tipo de Órgano",
                        "type": "array",
                        "description": "Tipo de órgano judicial. Los códigos son opacos: NO los adivines, lee el título (enumTitle) de cada opción y elige el que coincide exactamente con lo que pide el usuario. Para un órgano con varias salas (Tribunal Supremo, Audiencia Nacional, TSJ) usa el código combinado salvo que se precise una sala. Errores frecuentes a evitar: 'Juzgado de Primera Instancia' es el código 42 (NO 31, que es el Tribunal Superior de Justicia); la 'Sala de lo Civil del Tribunal Supremo' es 11 (NO 12, que es Penal); la 'Audiencia Provincial' es 37 (NO 42). Si no se indica ninguno, se busca en todos.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "11|12|13|14|15|16",
                                "11",
                                "12",
                                "13",
                                "14",
                                "15",
                                "16",
                                "22|2264|23|24|25|26|27|28|29",
                                "22",
                                "2264",
                                "23",
                                "24",
                                "27",
                                "26",
                                "25",
                                "29",
                                "28",
                                "31|31201202|33|34",
                                "31",
                                "31201202",
                                "33",
                                "34",
                                "37",
                                "38",
                                "1001",
                                "42",
                                "43",
                                "45",
                                "53",
                                "41",
                                "47",
                                "1002",
                                "51",
                                "44",
                                "52",
                                "48",
                                "83",
                                "85",
                                "75",
                                "36"
                            ],
                            "enumTitles": [
                                "Tribunal Supremo",
                                "Tribunal Supremo. Sala de lo Civil",
                                "Tribunal Supremo. Sala de lo Penal",
                                "Tribunal Supremo. Sala de lo Contencioso",
                                "Tribunal Supremo. Sala de lo Social",
                                "Tribunal Supremo. Sala de lo Militar",
                                "Tribunal Supremo. Sala de lo Especial",
                                "Audiencia Nacional",
                                "Audiencia Nacional. Sala de lo Penal",
                                "Sala de Apelación de la Audiencia Nacional",
                                "Audiencia Nacional. Sala de lo Contencioso",
                                "Audiencia Nacional. Sala de lo Social",
                                "Audiencia Nacional. Juzgados Centrales de Instrucción / Tribunal Central Instancia Sec. Instr.",
                                "Audiencia Nacional. Juzgado Central de Menores",
                                "Audiencia Nacional. Juzgado Central de Vigilancia Penitenciaria",
                                "Audiencia Nacional. Juzgados Centrales de lo Contencioso / Tribunal Central Instancia Sec. Contencioso",
                                "Audiencia Nacional. Juzgados Centrales de lo Penal",
                                "Tribunal Superior de Justicia",
                                "Tribunal Superior de Justicia. Sala de lo Civil y Penal",
                                "Sección de Apelación Penal. TSJ Sala de lo Civil y Penal",
                                "Tribunal Superior de Justicia. Sala de lo Contencioso",
                                "Tribunal Superior de Justicia. Sala de lo Social",
                                "Audiencia Provincial",
                                "Audiencia Provincial. Tribunal Jurado",
                                "Tribunal de Marca de la UE",
                                "Juzgado de Primera Instancia / Tribunal Instancia Sec. Civil",
                                "Juzgado de Instrucción",
                                "Juzgado de lo Contencioso Administrativo / Tribunal Instancia Sec. Contencioso-Administrativo",
                                "Juzgado de Menores / Tribunal Instancia Sec. Menores",
                                "Juzgado de 1ª Inst. Instr. / Tribunal Instancia Sec. Civil Instr.",
                                "Juzgado de lo Mercantil / Tribunal Instancia Sec. Mercantil",
                                "Juzgados de Marca de la UE",
                                "Juzgado de lo Penal / Tribunal Instancia Sec. Penal",
                                "Juzgado de lo Social / Tribunal Instancia Sec. Social",
                                "Juzgado de Vigilancia Penitenciaria / Tribunal Instancia Sec. Vigilancia Penitenciaria",
                                "Juzgado de Violencia sobre la Mujer",
                                "Tribunal Militar Territorial",
                                "Tribunal Militar Central",
                                "Consejo Supremo de Justicia Militar",
                                "Audiencia Territorial"
                            ]
                        }
                    },
                    "resolutionTypes": {
                        "title": "Tipo de Resolución",
                        "type": "array",
                        "description": "Selecciona uno o más tipos de resolución. Si no se selecciona ninguno, se buscará en todos.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "SENTENCIA",
                                "AUTO",
                                "ACUERDO"
                            ],
                            "enumTitles": [
                                "Sentencia",
                                "Auto",
                                "Acuerdo"
                            ]
                        }
                    },
                    "locations": {
                        "title": "Localización",
                        "type": "array",
                        "description": "Selecciona una o más Comunidades Autónomas. Si no se selecciona ninguna, se buscará en todas.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "ANDALUCÍA",
                                "ARAGÓN",
                                "ASTURIAS",
                                "BALEARES",
                                "CANARIAS",
                                "CANTABRIA",
                                "CASTILLA LA MANCHA",
                                "CASTILLA Y LEÓN",
                                "CATALUÑA",
                                "CEUTA",
                                "COMUNIDAD VALENCIANA",
                                "EXTREMADURA",
                                "GALICIA",
                                "LA RIOJA",
                                "MADRID",
                                "MELILLA",
                                "MURCIA",
                                "NAVARRA",
                                "PAÍS VASCO"
                            ],
                            "enumTitles": [
                                "Andalucía",
                                "Aragón",
                                "Asturias",
                                "Baleares",
                                "Canarias",
                                "Cantabria",
                                "Castilla La Mancha",
                                "Castilla y León",
                                "Cataluña",
                                "Ceuta",
                                "Comunidad Valenciana",
                                "Extremadura",
                                "Galicia",
                                "La Rioja",
                                "Madrid",
                                "Melilla",
                                "Murcia",
                                "Navarra",
                                "País Vasco"
                            ]
                        }
                    },
                    "maxResults": {
                        "title": "Número máximo de sentencias",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Define el número máximo de sentencias a extraer por cada término de búsqueda. Se pagina automáticamente de 50 en 50. El límite es 200 por ejecución.",
                        "default": 10
                    },
                    "paragraphs": {
                        "title": "Modo párrafos (pasajes clave)",
                        "minimum": 0,
                        "maximum": 20,
                        "type": "integer",
                        "description": "Si es mayor que 0, al extraer el texto de un PDF se devuelven solo ese número de PÁRRAFOS relevantes (los pasajes donde aparecen los términos buscados, en frases completas y priorizando los Fundamentos de Derecho) en lugar del texto íntegro. Ideal para análisis con un LLM (menos tokens). Aplica cuando se extrae texto (campo `pdfUrls`, o búsqueda con extracción de texto activada). 0 = texto completo.",
                        "default": 0
                    },
                    "paragraphTerms": {
                        "title": "Términos para los párrafos",
                        "type": "string",
                        "description": "Términos con los que localizar los pasajes en el modo párrafos. Si se deja vacío, se usa el propio término de búsqueda (en la vía `searchTerms`). Es recomendable rellenarlo cuando se usa `pdfUrls` (segunda ejecución), ya que ahí no hay término de búsqueda."
                    },
                    "dateFrom": {
                        "title": "Fecha desde",
                        "type": "string",
                        "description": "Fecha de resolución inicial (opcional). Se incluyen las sentencias dictadas a partir de esta fecha."
                    },
                    "dateTo": {
                        "title": "Fecha hasta",
                        "type": "string",
                        "description": "Fecha de resolución final (opcional). Se incluyen las sentencias dictadas hasta esta fecha."
                    },
                    "sortOrder": {
                        "title": "Ordenar por",
                        "enum": [
                            "Relevance",
                            "IN_FECHARESOLUCION:increasing",
                            "IN_FECHARESOLUCION:decreasing",
                            "IN_FECHAENTRADA:numberdecreasing",
                            "IP_TIPOORGANO:alphabetical",
                            "IP_TIPOORGANO:reversealphabetical"
                        ],
                        "type": "string",
                        "description": "Criterio de ordenación de los resultados. Por defecto se ordena por coincidencia (relevancia).",
                        "default": "Relevance"
                    },
                    "proxyConfiguration": {
                        "title": "Proxy",
                        "type": "object",
                        "description": "Configuración de proxy. CENDOJ bloquea las IP de datacenter, por lo que se recomienda usar proxy residencial de España (grupo RESIDENTIAL, país ES). El tráfico residencial se factura por GB consumido.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ],
                            "apifyProxyCountry": "ES"
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
