# CanLII Canadian Case Law Scraper (`jungle_synthesizer/canlii-canadian-case-law-scraper`) Actor

Collect Canadian court and tribunal decisions from CanLII by jurisdiction, court and year. Each record
carries the case name, neutral citation, court, decision date, docket number, the full judgment text,
and the cases and legislation the decision cites.

- **URL**: https://apify.com/jungle_synthesizer/canlii-canadian-case-law-scraper.md
- **Developed by:** [BowTiedRaccoon](https://apify.com/jungle_synthesizer) (community)
- **Categories:** Business, Education
- **Stats:** 2 total users, 1 monthly users, 80.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 record scrapeds

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

## CanLII Scraper: Canadian Case Law Database to JSON

Pulls court and tribunal decisions from CanLII by jurisdiction, court and year. Each record carries the neutral citation, the decision date, the docket number, the full judgment text, and the cases and legislation the decision cites.

***

### CanLII Scraper Features

- Collects decisions from the Supreme Court of Canada, the Federal Courts, the provincial and territorial courts, and the tribunals CanLII lists under each jurisdiction
- Returns the complete judgment text, or leaves it out when you only need the index
- Captures the citation graph: the CanLII path of every case a decision cites, and every statute section it points to
- Narrows by court code, by jurisdiction, and by a range of decision years, newest first
- Accepts CanLII decision, court and year-listing addresses directly
- Splits a busy year into months on its own, so a court that issues more than 500 decisions a year is still collected in full

***

### What can you do with Canadian case law data?

- **Legal researchers** — build a corpus of appellate decisions for one court and one period, then run your own analysis on the text
- **Legal-tech teams** — feed judgments and their citation graphs into search, summarisation or precedent-mapping tools
- **Academics** — study how often a court cites another, or how a doctrine moves across provinces, with the cited paths already extracted
- **Compliance and risk teams** — watch a tribunal's recent decisions for the regulator or sector you answer to
- **Journalists** — pull every decision a court issued in a month and read the ones that matter

***

### How CanLII Scraper works

1. Choose a jurisdiction, or name courts directly as `jurisdiction/court` (for example `ca/scc` or `on/onca`).
2. The scraper finds each court's decision listing, restricted to the years you ask for, and starts with the newest.
3. It opens every decision and returns one record, with the text and the citation graph.

***

### Input

```json
{
  "jurisdictions": ["ca"],
  "courts": ["ca/scc"],
  "yearFrom": 2023,
  "yearTo": 2024,
  "includeFullText": true,
  "maxItems": 50
}
```

| Field             | Type    | Default  | Description |
|-------------------|---------|----------|----------------------------------------------------------------------------------------------------------------------------------|
| `jurisdictions`   | array   | `["ca"]` | Jurisdictions to collect from: `ca` (federal), `ab`, `bc`, `mb`, `nb`, `nl`, `ns`, `nt`, `nu`, `on`, `pe`, `qc`, `sk`, `yt` |
| `courts`          | array   | empty    | Limit the run to specific courts, written `jurisdiction/court`. Empty means every court and tribunal under the chosen jurisdictions |
| `yearFrom`        | integer | newest   | Earliest decision year to collect |
| `yearTo`          | integer | newest   | Latest decision year to collect. With neither year set, each court contributes its newest year |
| `includeFullText` | boolean | `true`   | Return the judgment text. Turn off to keep records small |
| `startUrls`       | array   | empty    | CanLII decision pages, court pages or year listings. They replace jurisdictions and courts |
| `maxItems`        | integer | `5`      | Maximum number of decisions to return |

Court codes are the path segments CanLII uses in its own addresses. `ca/scc` is the Supreme Court of Canada, `ca/fca` the Federal Court of Appeal, `on/onca` the Court of Appeal for Ontario.

***

### CanLII Scraper Output Fields

```json
{
  "case_name": "Shot Both Sides v. Canada",
  "citation": "2024 SCC 12",
  "other_citations": ["490 DLR (4th) 585", "[2024] SCJ No 12 (QL)", "[2024] ACS no 12"],
  "court": "Supreme Court of Canada",
  "court_code": "ca/scc",
  "jurisdiction": "ca",
  "decision_date": "2024-04-12",
  "docket_number": "40153",
  "judgment_url": "https://www.canlii.org/en/ca/scc/doc/2024/2024scc12/2024scc12.html",
  "short_url": "https://canlii.ca/t/k40h4",
  "pdf_url": "https://www.canlii.org/en/ca/scc/doc/2024/2024scc12/2024scc12.pdf",
  "judgment_text": "SUPREME COURT OF CANADA\n\nCitation: Shot Both Sides v. Canada, 2024 SCC 12 ...",
  "cited_cases": ["/en/bc/bcca/doc/2020/2020bcca138/2020bcca138.html", "/en/ca/fca/doc/2022/2022fca20/2022fca20.html"],
  "cited_legislation": [{ "path": "/en/ca/laws/stat/schedule-b-to-the-canada-act-1982-uk-1982-c-11/latest/schedule-b-to-the-canada-act-1982-uk-1982-c-11.html", "text": "Constitution Act, 1982" }]
}
```

| Field               | Type   | Description                                                                                        |
|---------------------|--------|----------------------------------------------------------------------------------------------------|
| `case_name`         | string | Style of cause                                                                                     |
| `citation`          | string | Neutral citation                                                                                   |
| `other_citations`   | array  | Parallel citations printed on the decision page                                                    |
| `court`             | string | Court or tribunal name                                                                             |
| `court_code`        | string | Court code, such as `ca/scc`                                                                       |
| `jurisdiction`      | string | Jurisdiction code                                                                                  |
| `decision_date`     | string | Decision date, `YYYY-MM-DD`                                                                        |
| `docket_number`     | string | Docket or file number. Several are joined with a semicolon when a decision lists many              |
| `judgment_url`      | string | The CanLII decision page                                                                           |
| `short_url`         | string | CanLII short link                                                                                  |
| `pdf_url`           | string | PDF copy on CanLII                                                                                 |
| `judgment_text`     | string | Full judgment text. Empty when text is switched off, or when a decision is published only as a PDF |
| `cited_cases`       | array  | CanLII paths of the decisions this one cites                                                       |
| `cited_legislation` | array  | Legislation cited, each with its CanLII path and the section label                                 |

***

### FAQ

#### How do I scrape CanLII case law?

CanLII Scraper takes a jurisdiction or a list of court codes and a range of years, and returns one JSON record per decision. Set `courts` to `["ca/scc"]` and `yearTo` to `2024` and you get the Supreme Court's 2024 decisions, newest first.

#### What data can I get from CanLII?

CanLII Scraper returns the style of cause, neutral and parallel citations, court, decision date, docket number, the full judgment text, and the cases and statutes each decision cites. Keywords and headnotes are not part of the output.

#### Which courts does it cover?

CanLII Scraper covers whatever CanLII lists under a jurisdiction: federal courts and tribunals, the provincial and territorial courts, and the boards and tribunals beneath them. Legislation databases are not included.

#### Is the judgment text in English or French?

CanLII Scraper reads CanLII's English pages. A decision issued in French stays in French; the record is the same, the language is the court's.

#### How far back can I go?

CanLII Scraper goes back as far as a court's year listing does. Set `yearFrom` and `yearTo` to bound it, and `maxItems` to stop a run at the number of decisions you want.

#### How much does CanLII Scraper cost to run?

CanLII Scraper charges per decision returned, so a run that returns 50 decisions costs for 50. The Apify pricing panel on this page shows the current rate.

***

### Need More Features?

Need extra fields, another jurisdiction layout or a different legal database? [File an issue](https://console.apify.com/actors/issues) or get in touch.

### Why Use CanLII Scraper?

- **Whole decisions** — the judgment text and the citation graph arrive in one record, not spread across calls
- **Bounded by you** — pick the courts, the years and the count, and the run stops when it has them
- **Clean output** — consistent field names and ISO dates, so the data goes into a database or a model without a cleaning pass

# Actor input Schema

## `sp_intended_usage` (type: `string`):

What will this data feed? E.g. lead lists, KYB checks, price tracking.

## `sp_improvement_suggestions` (type: `string`):

Provide any feedback or suggestions for improvements.

## `sp_contact` (type: `string`):

We'll personally help with your use case. No spam.

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

Which jurisdictions to collect decisions from. Every court and tribunal CanLII lists under each
jurisdiction is crawled unless you narrow it with Courts. Federal covers the Supreme Court of Canada,
the Federal Courts, the Tax Court and the federal tribunals.

## `courts` (type: `array`):

Optional. Limit the crawl to specific courts or tribunals, written as jurisdiction/court as they appear in
CanLII addresses, for example ca/scc (Supreme Court of Canada), ca/fca (Federal Court of Appeal) or
on/onca (Court of Appeal for Ontario). Leave empty to crawl every court under the chosen jurisdictions.

## `yearFrom` (type: `integer`):

Earliest decision year to collect. Leave empty to start from the newest year each court has published.

## `yearTo` (type: `integer`):

Latest decision year to collect. Leave empty for the newest year each court has published. Years run
newest first.

## `includeFullText` (type: `boolean`):

Return the complete judgment text with each record. Turn off to keep records small.

## `startUrls` (type: `array`):

Optional. CanLII decision pages (.../doc/YYYY/.../....html), court pages (canlii.org/en/on/onca/) or
year listings (.../nav/date/2024). When set, they replace Jurisdictions and Courts.

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

Maximum number of decisions to return.

## Actor input object example

```json
{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "jurisdictions": [
    "ca"
  ],
  "courts": [],
  "includeFullText": true,
  "startUrls": [],
  "maxItems": 5
}
```

# Actor output Schema

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

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "jurisdictions": [
        "ca"
    ],
    "courts": [],
    "startUrls": [],
    "maxItems": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("jungle_synthesizer/canlii-canadian-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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "jurisdictions": ["ca"],
    "courts": [],
    "startUrls": [],
    "maxItems": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("jungle_synthesizer/canlii-canadian-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 '{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "jurisdictions": [
    "ca"
  ],
  "courts": [],
  "startUrls": [],
  "maxItems": 5
}' |
apify call jungle_synthesizer/canlii-canadian-case-law-scraper --silent --output-dataset

```

## MCP server setup

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