# Datajud Scraper (`normdata/datajud-scraper`) Actor

Query Brazil's official CNJ DataJud court records across 90+ tribunais. Look up cases by process number with the court found automatically, never a stale duplicate snapshot, plus full docket, class, subject and judging body. Watch a portfolio and get told only what genuinely changed.

- **URL**: https://apify.com/normdata/datajud-scraper.md
- **Developed by:** [Norm Data](https://apify.com/normdata) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $15.00 / 1,000 results

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

![Norm Data](https://i.ibb.co/rGbhM5Y8/Chat-GPT-Image-Sep-8-2026-02-20-50-PM.png)

## ⚖️ DataJud Scraper

Query the official **CNJ DataJud** database of Brazilian court processes across all 90+ tribunais,
with no login and no API key of your own to manage. Look up exact cases by process number, or
search a court by class, subject, judging body, instance and date, and get back the full
procedural docket. Built for legal due diligence, litigation monitoring, jurimetria and compliance
screening in Brazil.

### 🎯 Who uses it?

#### ⚖️ Law firms and legal ops

Track a portfolio of process numbers across scheduled runs and get told exactly which ones moved,
without re-checking every case by hand.

#### 🏢 KYB and litigation-risk teams

Pull every process tied to a class, subject or judging body across multiple courts before a deal,
and flag active versus dormant cases by days since the last movement.

#### 📊 Jurimetria and legal analysts

Build datasets of Brazilian court processes by class, subject, court and filing year for
statistical analysis of case flow and duration.

#### 💳 Credit and debt-recovery teams

Find execução and recuperação judicial cases by class and subject code to assess counterparty
exposure.

#### 🕵️ Journalists and researchers

Query public court records across state, federal, labor and superior courts for investigations.

### ✨ What it does

- **Lookup by process number**: give one or more 20-digit CNJ process numbers and get the full
  case back, with the right court found automatically from the number itself.
- **Search a court** (or several in parallel) by free text, procedural class, subject, judging
  body, instance, movement code, and filing or last-update date ranges.
- **Full procedural docket**: every movement in the case, with its date, the judging body that
  handled it, and any complement codes explaining why it happened.
- **Watch a portfolio**: opt in to only get told about cases with a genuinely new movement since
  the last run, instead of re-reading everything every time.
- **Sealed-case filter**: skip confidential processes when you only want public ones.

Missing source values are returned as `null`, never invented.

### Why this scraper

- **Finds the right court on its own.** Paste a process number and it works out which of the 90+
  courts holds it, instead of making you guess or list several courts just in case.
- **Never hands back a stale snapshot.** A single process number can have more than one matching
  record in a court's own index; this always keeps the most recently updated one.
- **A real watch mode, not just a date filter.** Remembers what it saw last time and reports only
  genuine changes, so a scheduled run tells you what actually moved.
- **Dates you can trust.** Court filing dates arrive in more than one raw format depending on the
  source system; both are parsed into one clean, consistent timestamp.
- **The complete docket, not a summary.** Every movement, with the judging body and complement
  codes CNJ itself publishes, not a trimmed subset.

### How it compares

| Capability | This actor | Other DataJud actors on Apify |
|---|:--:|:--:|
| Courts covered | 90+ | varies, some single-court only |
| **Automatic court detection from a process number** | **yes** | no, you list courts yourself |
| **Protection against stale duplicate records** | **yes** | not documented |
| **Portfolio watch mode (only report real changes)** | **yes** | manual date filtering only |
| Multi-court parallel search | yes | some |
| Class, subject, judging body, instance and movement filters | yes | rare |
| Full movement docket with complement codes | yes | rare |
| Sealed/confidential case filter | yes | no |

### 📦 What data you get

| Entity | Useful fields |
| --- | --- |
| Process | Number, court, instance, procedural class, primary and all subjects, filing date and year, confidentiality level. |
| Judging body | Name, code, and the IBGE municipality code of the court, when published. |
| Status | Last movement, its date, total movement count, and days since the last movement. |
| Docket | The complete movement history, each with its date, judging body and complement codes. |
| Monitor | Which movements are new since the last run, and whether the case changed at all. |

Every record includes `observedAt` (UTC). Download your dataset from Apify as CSV, JSON, Excel, or
XML.

### 💡 Use cases

#### ⚖️ Track a portfolio of cases for what changed

```json
{ "processNumbers": ["00182260520208260050"], "onlyChangedSinceLastRun": true }
```

#### 🏢 Every execution case in a court since a given date

```json
{ "tribunal": "tjsp", "classeCode": 386, "filedFrom": "2023-01-01", "maxCases": 200 }
```

#### 📊 Search several courts at once

```json
{ "tribunais": ["tjsp", "tjrj", "trt2"], "query": "recuperação judicial", "maxCases": 100 }
```

### ⚙️ How the input is organised

**Maximum cases** sits at the very top, since it applies no matter what you're doing. Below it,
the form is split into three numbered sections:

| Section | What it's for |
| --- | --- |
| **1 · What to search** | A court (or several) plus optional free text, or process numbers to look up directly. |
| **2 · Filters (optional)** | Class, subject, judging body, instance, movement and date-range filters, plus the sealed-case exclusion. Only apply when searching a court. |
| **3 · Monitor (optional)** | Turn on change-only reporting for a list of process numbers. |

> **Apify Free plan:** every run is limited to a fixed 10-row sample. Upgrade your Apify plan to
> run your own settings.

### 🛡️ Limits & responsible use

This Actor reads only publicly available CNJ DataJud data. It never signs in and never accesses
anything gated behind an account.

By CNJ policy, the public DataJud API does not publish party names, lawyers or the claim value of
a case, so those fields do not exist in this source and are never invented here. For decision text
or party information, a different source is needed.

If a process number can't be found in any of the courts checked, or a search matches nothing, the
run writes a single row with an `error` field instead of failing silently.

### 📧 Contact

Need a scraper for a different site, or found something wrong with this one? norm.data.scrapers@gmail.com

### Local development

```bash
bun install
bun test                # offline: normalization and input parsing, against real fixtures
bun run src/main.ts     # reads storage/key_value_stores/default/INPUT.json
```

# Changelog

This Actor's version history is a separate document: https://apify.com/normdata/datajud-scraper/changelog.md

# Actor input Schema

## `maxCases` (type: `integer`):

Stop once this many processes are in the dataset. *(Free plan: always capped at 10.)*

## `tribunal` (type: `string`):

A single DataJud court index to search.

## `tribunais` (type: `array`):

Search several courts at once, e.g. tjsp, tjrj, trt2. Overrides "Court" above when filled in.

## `processNumbers` (type: `array`):

20-digit CNJ process numbers, with or without punctuation. Takes priority over every field below: the court is detected from the number itself, so you do not need to know which court holds it.

## `query` (type: `string`):

Free text across class, subject and movement names, e.g. "recuperação judicial". Used only when searching by court, not with process numbers.

## `classeCode` (type: `integer`):

CNJ/TPU class code, e.g. 386 for Execução da Pena.

## `assuntoCode` (type: `integer`):

CNJ/TPU subject code.

## `orgaoJulgadorCode` (type: `integer`):

Code of the specific chamber/vara.

## `grau` (type: `string`):

e.g. G1, G2, JE, SUP.

## `movimentoCode` (type: `integer`):

Only processes containing this docket movement code, e.g. 246 for a sentence.

## `filedFrom` (type: `string`):

Only processes filed (dataAjuizamento) on or after this date.

## `filedTo` (type: `string`):

Only processes filed (dataAjuizamento) on or before this date.

## `updatedFrom` (type: `string`):

Only processes last updated (dataHoraUltimaAtualizacao) on or after this date.

## `updatedTo` (type: `string`):

Only processes last updated (dataHoraUltimaAtualizacao) on or before this date.

## `excludeSealed` (type: `boolean`):

Skip processes with a non-zero confidentiality level (nivelSigilo).

## `onlyChangedSinceLastRun` (type: `boolean`):

Remembers each case's last movement between runs and returns only the ones that changed, with the new movements listed. Needs "Process numbers" above.

## Actor input object example

```json
{
  "maxCases": 10,
  "tribunal": "tjsp",
  "tribunais": [],
  "processNumbers": []
}
```

# Actor output Schema

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

One dataset row per court process.

# 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 = {
    "maxCases": 10,
    "tribunal": "tjsp",
    "tribunais": [],
    "processNumbers": [],
    "excludeSealed": false,
    "onlyChangedSinceLastRun": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("normdata/datajud-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 = {
    "maxCases": 10,
    "tribunal": "tjsp",
    "tribunais": [],
    "processNumbers": [],
    "excludeSealed": False,
    "onlyChangedSinceLastRun": False,
}

# Run the Actor and wait for it to finish
run = client.actor("normdata/datajud-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 '{
  "maxCases": 10,
  "tribunal": "tjsp",
  "tribunais": [],
  "processNumbers": [],
  "excludeSealed": false,
  "onlyChangedSinceLastRun": false
}' |
apify call normdata/datajud-scraper --silent --output-dataset

```

## MCP server setup

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