# CEJ Scraper - Consulta de Expedientes Judiciales (`latam-data/cej-scraper`) Actor

Scrapes case details from Peru's CEJ (Consulta de Expedientes Judiciales) system given a case file number and party name.

- **URL**: https://apify.com/latam-data/cej-scraper.md
- **Developed by:** [latam-data](https://apify.com/latam-data) (community)
- **Categories:** Lead generation, Other, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $150.00 / 1,000 case records

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

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

⚖️ CEJ Scraper — Peru Court Case Lookup

Look up a case file (expediente) in Peru's judicial portal (CEJ — Consulta de Expedientes Judiciales) by case number and party name: judge, status, subject matter, all parties, and the full chronological case action history with notifications — plus optional attached-document downloads. Solves the site's captcha automatically. Built for legal monitoring, due diligence, and case tracking.

#### Output example (one record per run)

Field names mirror the source portal's terminology. Every case action (`caseActions[]`) carries its own `notificationsStatus[]` history.

```json
{
  "caseFileNumber": "00001-2020-0-1601-JP-CI-01",
  "judicialBody": "1° JUZGADO DE PAZ LETRADO - Ejemplo",
  "judicialDistrict": "LIMA",
  "judge": "JUAN PEREZ RAMIREZ",
  "legalSpecialist": "MARIA GARCIA TORRES",
  "startDate": "2020-01-15",
  "process": "SUMARISIMO",
  "speciality": "CIVIL",
  "subjectMatters": "OBLIGACION DE DAR SUMA DE DINERO",
  "status": "EN EJECUCION",
  "proceedingStage": "GENERAL",
  "conclusionDate": null,
  "summary": "DEMANDA DE OBLIGACION DE DAR SUMA DE DINERO",
  "parties": [
    {
      "partyType": "DEMANDADO",
      "personType": "NATURAL",
      "firstName": "CARLOS",
      "paternalLastName": "SANCHEZ",
      "maternalLastName": "FLORES",
      "businessName": null
    }
  ],
  "caseActions": [
    {
      "actionType": "AUTO",
      "rulingNumber": "DIEZ",
      "rulingIssuedDate": "2026-05-04",
      "summary": "HOMOLÓGUESE LA TRANSACCIÓN EXTRAJUDICIAL PRESENTADA POR LAS PARTES...",
      "hasAttachedDocument": true,
      "documentKey": "00001-2020-0-1601-jp-ci-01_010-resolucion.pdf",
      "notificationsStatus": [
        {
          "code": "NOTIFICACIÓN 2026-0000001-JP-CI",
          "recipient": "GARCIA TORRES MARIA",
          "notifiedDate": "2026-05-04"
        }
      ]
    }
  ]
}
```

Abbreviated sample — real output includes every field on every case action and notification (dates, folios/fojas counts, delivery details). Set `downloadDocuments: true` to also save each attached ruling/filing PDF to the run's Key-Value Store, with `documentKey` pointing to it; otherwise `caseActions[].hasAttachedDocument` just flags whether one exists.

#### Try it: input and API

**Input** (Console Input tab, or via API):

```json
{
  "caseFileNumber": "00001-2020-0-1601-JP-CI-01",
  "parte": "SANCHEZ FLORES",
  "downloadDocuments": false
}
```

**Run and get results back synchronously** (blocks until the scrape finishes, ~30-90s, then returns the dataset items directly):

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_USERNAME~cej-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"caseFileNumber":"00001-2020-0-1601-JP-CI-01","parte":"SANCHEZ FLORES"}'
```

Or trigger an async run with `POST /v2/acts/{actorId}/runs` and poll/webhook for completion. Export the dataset as JSON, CSV or XLSX from the Console.

#### What this Actor returns

| | |
|---|---|
| 🔑 **Case identity** | `caseFileNumber`, `judicialBody`, `judicialDistrict`, `judge`, `legalSpecialist`, `startDate` |
| 📋 **Case status** | `process`, `speciality`, `subjectMatters`, `status`, `proceedingStage`, `conclusionDate`, `conclusionReason`, `summary` |
| 👥 **Parties** | `parties[]`: role (`partyType`), person or company (`personType`), name fields |
| 📄 **Case actions** | `caseActions[]`: filings, rulings and decrees in chronological order, each with `hasAttachedDocument` / `documentKey` |
| 🔔 **Notifications** | `caseActions[].notificationsStatus[]`: delivery status per party for each ruling |

#### Why look up a Peru court case (expediente) by case number?

- **Legal monitoring**: track a case's status and new rulings without manually visiting the portal
- **Due diligence**: check a counterparty's litigation history before a deal
- **Law firm ops**: pull structured case data into your own case-management system
- **Document archival**: automatically download every attached ruling/filing PDF as the case progresses

Data comes directly from Peru's official CEJ portal (cej.pj.gob.pe) at scrape time.

#### Limits

- One case per run (`caseFileNumber` + `parte`)
- Captcha solving retries automatically (up to 20 attempts) before failing the run
- `downloadDocuments: true` adds one extra request per case action with an attached file

#### FAQ

**Does it download the actual documents (PDFs)?**
Yes, when `downloadDocuments: true` — each `caseActions[]` entry with an attachment gets fetched and stored in the run's Key-Value Store, referenced by `documentKey`. Without it, you still get `hasAttachedDocument: true/false` per action at no extra cost.

**What if the case or party name doesn't match?**
The run fails with a "case not found" error — `parte` must match a party name as it appears on the portal.

**Why does a run sometimes take longer than others?**
The site's captcha isn't always solved on the first try; the Actor retries automatically (up to 20 times) before giving up.

**What case file number format is expected?**
The 7-segment format used by the Peruvian judiciary: `XXXXX-YYYY-Z-DDDD-AA-BB-CC` (e.g. `00001-2020-0-1601-JP-CI-01`).

***

#### 🇵🇪 Resumen en español

Este Actor consulta expedientes judiciales del Perú en el portal CEJ (Consulta de Expedientes Judiciales) por número de expediente y nombre de parte: juez, estado, materia, partes intervinientes e historial completo de actuaciones judiciales con su estado de notificación, resolviendo el captcha del sitio automáticamente. Con `downloadDocuments: true` también descarga los documentos adjuntos (resoluciones, escritos) al Key-Value Store de la ejecución. Ideal para seguimiento de casos, debida diligencia legal y automatización de estudios jurídicos.

# Actor input Schema

## `caseFileNumber` (type: `string`):

Case file number in 7-segment format: XXXXX-YYYY-Z-DDDD-AA-BB-CC (e.g. 00038-2017-0-1611-JP-CI-01)

## `parte` (type: `string`):

Enter both surnames (paternal and maternal) or the company name (razón social) of one of the parties involved in the case — exactly as, and in the same order as, they appear in the case's rulings (e.g. 'LOZANO OLIVARES').

## `downloadDocuments` (type: `boolean`):

Download attached documents and store them in the Key-Value Store

## Actor input object example

```json
{
  "caseFileNumber": "00038-2017-0-1611-JP-CI-01",
  "parte": "LOZANO OLIVARES",
  "downloadDocuments": false
}
```

# Actor output Schema

## `caseData` (type: `string`):

Full case details, parties, and case action history

## `documents` (type: `string`):

Attached documents downloaded when downloadDocuments is enabled

# 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 = {
    "caseFileNumber": "00038-2017-0-1611-JP-CI-01",
    "parte": "LOZANO OLIVARES"
};

// Run the Actor and wait for it to finish
const run = await client.actor("latam-data/cej-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 = {
    "caseFileNumber": "00038-2017-0-1611-JP-CI-01",
    "parte": "LOZANO OLIVARES",
}

# Run the Actor and wait for it to finish
run = client.actor("latam-data/cej-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "caseFileNumber": "00038-2017-0-1611-JP-CI-01",
  "parte": "LOZANO OLIVARES"
}' |
apify call latam-data/cej-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/EvGCmxP5hXiaGt7Dh/builds/NPSbEr6amzSxHFStS/openapi.json
