Discover/Edu API
live

Edu APIaustlii.edu.au

Access AustLII's Australian legal databases via API. Browse court decisions by year, list cases, and retrieve RTF, PDF, and print-friendly download links.

Endpoints
4
Updated
2mo ago

What is the Edu API?

The AustLII API provides 4 endpoints to discover, browse, and retrieve Australian legal case documents from AustLII (australasian Legal Information Institute). The list_databases endpoint enumerates every available jurisdiction and court database with its path identifier, which you then pass to get_database_years, list_cases, and get_case to navigate and download decisions in RTF, PDF, or eco-friendly print formats.

Try it

No input parameters required.

api.parse.bot/scraper/6c24f681-35dd-4b59-b1c9-216b3fc16289/<endpoint>
Ready to send
Fill in the parameters and hit sign in to send to see live response data here.
Call it over HTTPgrab a free API key at signup
curl -X GET 'https://api.parse.bot/scraper/6c24f681-35dd-4b59-b1c9-216b3fc16289/list_databases' \
  -H 'X-API-Key: $PARSE_API_KEY'
Python SDK · recommended

Typed, relational, agent-ready

A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.

  • Fully typed · autocompletes
  • Objects link to objects
  • Typed errors & pagination

Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:

uv add parse-sdk
uv run parse init
uv run parse add --marketplace austlii-edu-au-api

uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.

"""
AustLII Legal Case Scraper - ParseClient Implementation

Get your API key from: https://parse.bot/settings
"""

import os
import requests
from typing import Optional, Any


class ParseClient:
    """Client for interacting with the AustLII Legal Case Scraper API."""
    
    def __init__(self, api_key: Optional[str] = None):
        """
        Initialize the ParseClient.
        
        Args:
            api_key: API key for Parse API. If not provided, reads from PARSE_API_KEY environment variable.
        """
        self.base_url = "https://api.parse.bot"
        self.scraper_id = "6c24f681-35dd-4b59-b1c9-216b3fc16289"
        self.api_key = api_key or os.getenv("PARSE_API_KEY")
        
        if not self.api_key:
            raise ValueError("API key must be provided or set in PARSE_API_KEY environment variable")
    
    def _call(self, endpoint: str, method: str = "POST", **params) -> dict[str, Any]:
        """
        Make a request to the Parse API.
        
        Args:
            endpoint: The API endpoint name
            method: HTTP method (GET or POST)
            **params: Parameters to pass to the endpoint
            
        Returns:
            The JSON response from the API
        """
        url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
        headers = {
            "X-API-Key": self.api_key,
            "Content-Type": "application/json"
        }
        
        if method == "GET":
            response = requests.get(url, headers=headers, params=params)
        elif method == "POST":
            response = requests.post(url, headers=headers, json=params)
        else:
            raise ValueError(f"Unsupported HTTP method: {method}")
        
        response.raise_for_status()
        return response.json()
    
    def list_databases(self) -> dict[str, Any]:
        """
        List all available legal databases on AustLII organized by jurisdiction and category.
        
        Returns:
            Dictionary containing list of databases with their metadata
        """
        return self._call("list_databases", method="GET")
    
    def get_database_years(self, path: str) -> dict[str, Any]:
        """
        List all available years for a specific database.
        
        Args:
            path: The database path (e.g. 'cgi-bin/viewdb/au/cases/cth/HCA')
            
        Returns:
            Dictionary containing list of available years for the database
        """
        return self._call("get_database_years", method="GET", path=path)
    
    def list_cases(self, path: str, year: Optional[str] = None) -> dict[str, Any]:
        """
        List cases for a specific database and year.
        
        Args:
            path: The database path (e.g. 'cgi-bin/viewdb/au/cases/cth/HCA')
            year: The year (e.g. '2024'). If not provided, lists all cases
            
        Returns:
            Dictionary containing list of cases for the specified database and year
        """
        params = {"path": path}
        if year:
            params["year"] = year
        return self._call("list_cases", method="GET", **params)
    
    def get_case(self, url: str) -> dict[str, Any]:
        """
        Retrieve detailed metadata and download links for a specific case document.
        
        Args:
            url: The URL of the case document page
            
        Returns:
            Dictionary containing case metadata and download links
        """
        return self._call("get_case", method="GET", url=url)


def main():
    """Practical workflow demonstrating the ParseClient with real use case."""
    
    # Initialize the client
    client = ParseClient()
    
    print("=" * 90)
    print("AustLII Legal Case Scraper - Practical Usage Example")
    print("=" * 90)
    
    # Step 1: List all available databases
    print("\n[Step 1] Fetching all available legal databases from AustLII...")
    try:
        databases_response = client.list_databases()
        databases = databases_response.get("data", {}).get("databases", [])
    except Exception as e:
        print(f"Error fetching databases: {e}")
        return
    
    print(f"✓ Found {len(databases)} databases across all jurisdictions\n")
    
    # Group databases by jurisdiction for display
    jurisdictions = {}
    for db in databases:
        jurisdiction = db.get("jurisdiction", "Unknown")
        if jurisdiction not in jurisdictions:
            jurisdictions[jurisdiction] = []
        jurisdictions[jurisdiction].append(db)
    
    # Display first few jurisdictions
    print("Available Jurisdictions:")
    for i, (jurisdiction, dbs) in enumerate(list(jurisdictions.items())[:3]):
        print(f"  • {jurisdiction}: {len(dbs)} database(s)")
    
    # Find the High Court of Australia database as an example
    print("\n[Step 2] Searching for High Court of Australia database...")
    hca_db = None
    for db in databases:
        if "High Court of Australia" in db.get("database_name", ""):
            hca_db = db
            break
    
    if not hca_db:
        print("High Court of Australia database not found. Using first available database.")
        hca_db = databases[0] if databases else None
    
    if not hca_db:
        print("✗ No databases found!")
        return
    
    print(f"✓ Selected: {hca_db['database_name']}")
    print(f"  Jurisdiction: {hca_db['jurisdiction']}")
    print(f"  Category: {hca_db['category']}")
    
    # Step 3: Get available years for the selected database
    db_path = hca_db["path"]
    print(f"\n[Step 3] Fetching available years for: {hca_db['database_name']}...")
    try:
        years_response = client.get_database_years(path=db_path)
        years = years_response.get("data", {}).get("years", [])
    except Exception as e:
        print(f"Error fetching years: {e}")
        return
    
    print(f"✓ Found {len(years)} years with available cases")
    print(f"  Years available: {', '.join(years[:5])}{'...' if len(years) > 5 else ''}")
    
    # Step 4: List cases for the most recent year
    if years:
        recent_year = years[0]
        print(f"\n[Step 4] Listing cases from {recent_year}...")
        try:
            cases_response = client.list_cases(path=db_path, year=recent_year)
            cases = cases_response.get("data", {}).get("cases", [])
            total_count = cases_response.get("data", {}).get("count", 0)
        except Exception as e:
            print(f"Error fetching cases: {e}")
            return
        
        print(f"✓ Found {total_count} cases in {recent_year}")
        
        # Step 5: Get detailed information for multiple cases
        print(f"\n[Step 5] Retrieving details for the first {min(3, len(cases))} cases...")
        print("-" * 90)
        
        for i, case in enumerate(cases[:3], 1):
            try:
                case_details = client.get_case(url=case["url"])
                case_data = case_details.get("data", {})
                
                print(f"\nCase {i}:")
                print(f"  Title: {case_data.get('title', 'N/A')[:80]}")
                
                downloads = case_data.get("downloads", {})
                priority_url = case_data.get("priority_download_url", "N/A")
                
                print(f"  Priority Download Format: {priority_url.split('.')[-1].upper() if priority_url != 'N/A' else 'N/A'}")
                
                available_formats = [fmt.replace('_', ' ').title() for fmt in downloads.keys() if downloads[fmt]]
                print(f"  Available Formats: {', '.join(available_formats)}")
                
            except Exception as e:
                print(f"\n  ✗ Error retrieving case details: {e}")
        
        print("\n" + "-" * 90)
    else:
        print("✗ No years found for this database.")
    
    print("\n" + "=" * 90)
    print("✓ Workflow completed successfully!")
    print("=" * 90)


if __name__ == "__main__":
    main()
All endpoints · 4 totalmissing one? ·

Lists all available legal databases on AustLII organized by jurisdiction and category. Returns database names, URLs, and path identifiers that can be used with other endpoints.

Input

No input parameters required.

Response
{
  "type": "object",
  "fields": {
    "databases": "array of objects with jurisdiction, category, database_name, url, and path"
  },
  "sample": {
    "data": {
      "databases": [
        {
          "url": "https://www.austlii.edu.au/cgi-bin/viewdb/au/cases/cth/HCA/",
          "path": "cgi-bin/viewdb/au/cases/cth/HCA",
          "category": "Cth Case law",
          "jurisdiction": "Commonwealth of Australia",
          "database_name": "High Court of Australia 1903-"
        }
      ]
    },
    "status": "success"
  }
}

About the Edu API

Database Discovery and Navigation

The list_databases endpoint requires no parameters and returns an array of database objects, each carrying a jurisdiction, category, database_name, url, and path. The path field (e.g. cgi-bin/viewdb/au/cases/cth/HCA) is the key input for every subsequent endpoint. get_database_years accepts that path and returns the available years for that court database in descending order, letting you confirm temporal coverage before fetching case lists.

Listing and Filtering Cases

list_cases accepts the same path parameter and an optional year string (four digits, e.g. 2024). When year is omitted, the endpoint returns the database's default listing. The response includes cases — an array of objects with title and url — plus a count integer so you know how many results came back without iterating the array. Supplying a year filter narrows results to decisions from that calendar year.

Case Document Retrieval

get_case accepts the url from a list_cases result and returns structured metadata: the title, a downloads object keyed by format (rtf, pdf, eco_friendly_print) each mapping to its download URL, the source_url that was queried, and a priority_download_url that resolves to the best available format — RTF first, then eco-friendly print, then PDF. This means your application can always request priority_download_url and receive a usable link regardless of which formats a given case exposes.

Reliability & maintenance

The Edu API is a managed, monitored endpoint for austlii.edu.au — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when austlii.edu.au changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.

This isn't an official austlii.edu.au API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.

Will this API break when the source site changes?+
It's built not to. Every endpoint is health-checked on a schedule with automated test probes. When the source site changes and a check fails, the API is automatically queued for repair and re-verified — that's the self-healing layer. Each API page shows when its endpoints were last verified. And because marketplace APIs are shared, any fix reaches everyone using it.
Is this an official API from the source site?+
No — Parse APIs are independent, managed REST wrappers over publicly available data. That is the point: where a site has no official API (or only a limited one), Parse gives you a maintained, monitored endpoint for that data and keeps it working as the site changes — so you get a stable contract over a source that never promised one.
Can I fix or extend this API myself if I need a new endpoint or field?+
Yes — and you don't have to wait on us. This API was generated by the Parse agent, which stays attached. Describe the change in plain English ("add an endpoint that returns reviews", "fix the price field") in the revise box on the API page or via the revise_api MCP tool, and the agent rebuilds it against the live site in minutes. Contributing the change back to the public API is free.
What happens if I call an endpoint that has an issue?+
Errors are machine-readable: a bad call returns a clean status with the list of available endpoints and a repair hint, so an agent (or you) can recover or trigger a fix instead of failing silently. Confirmed failures feed the automatic repair queue.
Common use cases
  • Building a case law archive that mirrors AustLII databases by jurisdiction using list_databases path identifiers
  • Tracking new High Court decisions by year using get_database_years and list_cases with a year filter
  • Automating bulk RTF downloads of court decisions via priority_download_url for offline legal research
  • Generating a structured catalogue of Australian federal and state court decisions with titles and URLs
  • Feeding case document URLs into a document analysis pipeline using get_case download links
  • Monitoring a specific database's annual case volume by comparing count values returned by list_cases across years
Pricing & limitsSee full pricing →
TierPriceCredits/monthRate limit
Free$0/mo1005 req/min
Hobby$30/mo1,00020 req/min
Developer$100/mo5,000100 req/min

One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.

Frequently asked questions
Does AustLII provide an official developer API?+
AustLII does not publish a documented public REST API for programmatic case retrieval. The AustLII website (austlii.edu.au) is designed for browser-based access.
What does `get_case` return and how does format priority work?+
It returns the case title, a downloads object with up to three keys — rtf, pdf, and eco_friendly_print — each pointing to a direct download URL, plus a priority_download_url that resolves to RTF if available, then eco-friendly print, then PDF. Not every case exposes all three formats; priority_download_url always surfaces the best available one.
Does the API support full-text search across AustLII case content?+
Not currently. The API covers database discovery, year browsing, case listing, and case document metadata with download links. You can fork it on Parse and revise to add a search endpoint against AustLII's query interface.
Are non-case legal materials like legislation or journals available?+
list_databases returns all databases organised by category, which may include legislation and journal databases alongside case law. However, list_cases and get_case are oriented toward case documents; response fields like title and downloads assume a case document structure. Non-case material may not expose the same download formats. You can fork the API on Parse and revise to handle legislation-specific document structures.
Does `list_cases` paginate results for large databases?+
The endpoint returns a count field alongside the cases array, but the current response shape does not include pagination parameters like page or offset. For databases with large case volumes this means results may be capped at the source's default listing size. You can fork the API on Parse and revise to add pagination support.
Page content last updated . Spec covers 4 endpoints from austlii.edu.au.
Related APIs in Government PublicSee all →
bailii.org API
Search and retrieve court judgments and case law from British and Irish courts across multiple jurisdictions, with filtering by date range and location. Access complete case details including full judgment text and metadata to research legal precedents and decisions.
canlii.org API
Access Canadian legal information from CanLII.org. Discover jurisdictions and databases, search case law and legislation across all provinces and territories, and retrieve full document text and metadata.
examplecourt.gov API
Search and retrieve court judgments, case details, and legal metadata from a national court reporting portal, with support for advanced filtering by court and case category. Access complete case information including full text and browse paginated results to find relevant legal precedents.
justia.com API
Access Justia's legal database: search the lawyer directory by practice area and location, retrieve attorney profiles, browse state statutes and case law, explore legal guides, and look up law schools — all in one API.
scholar.google.com API
Search and retrieve case law from Google Scholar by keyword, with optional filtering by date range and court type. Fetch full case details including citations, court, and opinion text for any case returned by search.
indiankanoon.org API
indiankanoon.org API
livelaw.in API
Access Supreme Court and High Court judgments, legal news, articles, and digests from LiveLaw.in, with the ability to filter by year, category, and author. Stay updated on the latest legal developments, court decisions, and expert legal analysis across Indian courts.
ecourtsindia.com API
Search and retrieve detailed information about court cases across India's Supreme Court, High Courts, and District Courts from a database of over 239 million cases. Find case details, track legal proceedings, and access comprehensive court records to stay informed about judicial matters across the Indian court system.