# FindLaw.com Lawyer Directory Scraper (`memo23/findlaw-scraper`) Actor

Scrape lawyers.findlaw.com — one row per firm with every office address (lat/long), every attorney on staff, practice areas, website, and price range. Multi-select practice × state × city, or paste any FindLaw URL. JSON/CSV, billed per result.

- **URL**: https://apify.com/memo23/findlaw-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Lead generation, Automation, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 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.

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

## FindLaw.com Lawyer Directory Scraper

**Turn FindLaw.com into a structured US law-firm dataset.** Scrape every law firm + attorney profile from any FindLaw listing URL — name, legal name, full street address with real lat/long coordinates, multiple offices, telephone, practice areas, employees (attorneys at the firm with their own profile URLs), website, LinkedIn, price range, description — straight out of the page. JSON or CSV out, no compute charge per run, just per result.

#### How it works

![How FindLaw Scraper works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-findlaw.png)

#### ✨ Why use this scraper?

Building a US legal-marketing list? Mapping firm density by practice area + state? Need a clean firm dataset with all branch offices and named attorneys?

- 🎯 **Three ways to start.** Pick **practice areas + US states + optional cities** from the dropdowns (multi-select cartesian product), paste any FindLaw URL — listings or direct profile pages — or combine both. URLs always win.
- 🏢 **Firm-centric data shape.** One row per firm/profile with `name`, `legalName`, full address, geo coordinates, multiple offices (`locations[]`), and the entire roster of attorneys at the firm (`employees[]`) with their individual FindLaw profile URLs.
- 📍 **Real coordinates, not just zip codes.** Each row carries `coordinates.latitude` + `coordinates.longitude` parsed straight from the JSON-LD `geo` block — drop firms onto a map without a geocoding step.
- 🌐 **`website` and `linkedin` separated.** First non-social URL goes to `website`, any LinkedIn URL goes to `linkedin` — the full `sameAs[]` array is preserved too.
- 🏛 **All branch offices captured.** `locations[]` contains every office the firm lists — main + satellites — each with its own street address, postal code, and phone number.
- 👥 **Attorneys nested.** `employees[]` lists each attorney at the firm with their `name`, `jobTitle`, `image`, and individual FindLaw `profileUrl` — useful as a hop list if you also want per-attorney data.
- ⚡ **Two output modes.** Default fetches each firm's detail page for the full ~25-field profile. **Lite mode** skips per-firm fetches entirely — one listing fetch yields ~30 rows with name + phone + city/state. ~30× faster, ~30× cheaper.
- 🛡 **Cloudflare-aware, zero browser automation.** Three-stack TLS race (impit + got-scraping + curl-impersonate Chrome 131) handles the anti-bot layer without spinning up a headless Chromium.
- 📤 **Clean exports.** One row per firm. No padding rows, no duplicate office rows. JSON + CSV exported automatically.

#### 🎯 Use cases

| Team | What they build |
|------|-----------------|
| **Legal marketing / SaaS GTM** | Outbound lists for vendors selling to small/mid law firms — by state, city, and practice area |
| **Legal-tech research** | Firm-density maps, average roster size, branch-office distribution per metro |
| **Lead-gen / referral networks** | Build local firm directories or referral matchmaking by practice area + city |
| **Competitive intelligence** | Competitor benchmarking — staffing levels, branch-office expansion, practice-area coverage |
| **Journalists / academic research** | Studies on legal-services access by region |
| **Existing platforms enriching their data** | Patching firm records with verified phone, full address, geo coords, named attorneys, and website |

#### 📥 Supported inputs

The scraper accepts inputs in two mutually-exclusive modes — **URLs take strict precedence over filters**:

> ⚠️ **Precedence rule.** If `startUrls` has any non-empty entry, the practice-area / state / city dropdowns are completely ignored. To use the dropdowns, leave `startUrls` empty.

##### Mode 1 — Paste FindLaw URLs (highest priority)

Drop one or more lawyers.findlaw.com URLs into `startUrls`. Each URL is classified automatically:

| URL pattern | Behaviour |
|---|---|
| `https://lawyers.findlaw.com/{practice-area}/{state}/{city}/` | **Listing** — extracts firm links + walks pagination |
| `https://lawyers.findlaw.com/{practice-area}/{state}/` | **Listing** (state-level) |
| `https://lawyers.findlaw.com/{practice-area}/` | **Listing** (national) |
| `https://lawyers.findlaw.com/{state}/` | **Listing** (browse by state) |
| `https://lawyers.findlaw.com/{state}/{city}/{firm-slug}-{base64-id}/` | **Firm detail** — routed straight to the profile parser |

Easiest workflow: apply your filters on lawyers.findlaw.com in the browser, copy the URL from the address bar, paste into `startUrls`.

##### Mode 2 — Practice area + US state (+ optional city) dropdowns

All three dropdowns are **multi-select**. The scraper expands the cartesian product:

- **Practice areas** — 31 options (`family-law`, `criminal-law`, `personal-injury-plaintiff`, `real-estate-law`, etc.)
- **U.S. states** — all 50 states + DC
- **Cities** (optional) — narrow to specific cities (e.g. `los-angeles`, `san-francisco`)

````

{family-law, divorce} × {ca, ny} × {los-angeles, new-york}
→ 8 listing URLs (cartesian product)

````

**Edge cases:**
- States selected, no practice area → state-level browse listings (one per state).
- Practice area(s) selected, no states → national listings (one per practice area).
- No filters at all → falls back to a default LA family-law listing.

**Not supported:**

- FindLaw legal articles, Q&A, and the Marketing Solutions site (the scraper targets `lawyers.findlaw.com` profiles only)
- Hosts outside `lawyers.findlaw.com`

#### 🔄 How it works

1. **Resolve start URLs.** Synthesize listing URLs from the practice-area + state + city dropdowns (cartesian product) — or use `startUrls` if set (URL always wins).
2. **Classify each URL** as a listing or a firm profile.
3. **Fetch each listing** and pull every firm profile link from the embedded JSON-LD `CollectionPage > mainEntity.itemListElement[]`. ~30 firms per listing page.
4. **Follow pagination** by walking `?page=N` until either no `rel="next"` link exists or `maxItems` is reached.
5. **Fetch each firm detail page** in parallel through a global sliding window.
6. **Parse the JSON-LD `LegalService` block** for name, description, phone, full address, geo coordinates, multiple offices, employees, practice areas, website. Inline the main address into `locations[0]` (FindLaw uses an `@id` reference there).
7. **Push one row per firm** to the dataset and export `data.csv` + `data.json` at the end.

#### 🪶 Lite mode

Toggle `liteMode` on and the scraper extracts data directly from each listing page's embedded `LegalService` items — no per-firm detail HTTP calls. Trade-off:

- **~30× faster + ~30× cheaper.** One listing fetch yields ~30 rows.
- **Smaller field set.** `name`, `telephone`, `image`, `addressLocality` (city), `addressRegion` (state), `addressCountry`, `priceRange`. **Not in lite mode:** description, geo coordinates, multiple offices, employees, practice areas, website, LinkedIn, full street address.

Use lite mode for cheap, large-scale lead-gen runs where you only need name + phone + city. Use full mode for CRM enrichment, competitive intelligence, or any workflow that needs offices, employees, practice areas, or website data.

#### ⚙️ Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | `["https://lawyers.findlaw.com/family-law/california/los-angeles/"]` | Optional FindLaw URLs to crawl directly. Listing pages and firm-profile URLs both supported. **Takes precedence over the dropdowns below.** |
| `searchByCategory` | array (enum) | `["family-law"]` | Practice-area slugs (31 options). **Multi-select.** Combined with states + cities as a cartesian product. |
| `searchByLocation` | array (enum) | `["california"]` | US state slugs (51 options including DC). **Multi-select.** Empty = national listings. |
| `searchByCity` | array (string) | `["los-angeles"]` | Optional city slugs. **Multi-select.** When set, narrows to `/{practice-area}/{state}/{city}/`. |
| `liteMode` | boolean | `false` | Skip per-firm detail fetches; emit one row per listing card. ~30× faster but smaller field set. |
| `maxItems` | integer | `1000` | Hard cap on firm profiles collected. Listings paginate ~30 per page. |
| `maxConcurrency` / `minConcurrency` | integer | `10` / `1` | Parallel HTTP request limits. |
| `maxRequestRetries` | integer | `5` | Retries before a request is given up. |
| `proxy` | object | Apify residential, US | Proxy configuration. FindLaw serves Cloudflare on listing + detail pages — a US residential pool is strongly recommended. |

#### 📊 Output overview

Each scraped firm is one **single dataset row** of `type: "firm"`. There are no separate rows for offices or employees — both are nested arrays on the same firm row, so the dataset row count equals the firm count exactly.

#### 📦 Output sample

One row per firm (trimmed to the most useful fields):

```json
{
    "type": "firm",
    "firmId": "Mzc1MjA3NV8x",
    "id": "Mzc1MjA3NV8x",
    "url": "https://lawyers.findlaw.com/california/los-angeles/the-law-offices-of-teresa-a-beyers-Mzc1MjA3NV8x/",
    "profileUrl": "https://lawyers.findlaw.com/california/los-angeles/the-law-offices-of-teresa-a-beyers-Mzc1MjA3NV8x/",
    "name": "The Law Offices of Teresa A. Beyers",
    "legalName": "The Law Offices of Teresa A. Beyers",
    "description": "The Law Offices of Teresa A. Beyers, a Los Angeles, United States Law Firm - Family Law, Divorce, Custody",
    "bioSummary": "The Law Offices of Teresa A. Beyers, a Los Angeles, United States Law Firm - Family Law, Divorce, Custody",
    "image": "https://lawyers.findlaw.com/static/c/images/.../the_law_offices_of_teresa_a_beyers.jpg",
    "telephone": "+1-213-933-6681",
    "primaryPhone": "2139336681",
    "address": "355 S Grand Ave Ste 2450, Los Angeles, CA",
    "streetAddress": "355 S Grand Ave Ste 2450",
    "addressLocality": "Los Angeles",
    "addressRegion": "CA",
    "city": "Los Angeles",
    "state": "CA",
    "postalCode": "90071",
    "addressCountry": "US",
    "coordinates": { "latitude": 34.052536, "longitude": -118.2526779 },
    "practiceAreas": ["Family Law", "Divorce", "Custody", "Child Support"],
    "areaServed": ["California"],
    "numberOfEmployees": 1,
    "employees": [
        {
            "name": "Teresa A. Beyers",
            "jobTitle": null,
            "profileUrl": "https://lawyers.findlaw.com/california/los-angeles/teresa-a-beyers-Mzc1MzQy.../",
            "image": "https://lawyers.findlaw.com/static/c/images/.../teresa_a_beyers.jpg"
        }
    ],
    "locations": [
        {
            "name": "The Law Offices of Teresa A. Beyers - Main Office",
            "streetAddress": "355 S Grand Ave Ste 2450",
            "addressLocality": "Los Angeles",
            "addressRegion": "CA",
            "postalCode": "90071",
            "addressCountry": "US",
            "telephone": "+1-213-933-6681",
            "profileUrl": null
        },
        {
            "name": "The Law Offices of Teresa A. Beyers - Newport Beach Office",
            "streetAddress": "620 Newport Center Dr ## 1100",
            "addressLocality": "Newport Beach",
            "addressRegion": "CA",
            "postalCode": "92660",
            "addressCountry": null,
            "telephone": "213-933-6681",
            "profileUrl": "https://lawyers.findlaw.com/california/newport-beach/the-law-offices-of-teresa-a-beyers-NTM3ODk0NV8x/"
        }
    ],
    "website": "https://www.teresabeyersfamilylaw.com",
    "linkedin": null,
    "sameAs": ["https://www.teresabeyersfamilylaw.com"],
    "priceRange": "Varies based on case specifics",
    "currenciesAccepted": "USD",
    "ogImage": "https://lawyers.findlaw.com/static/c/images/.../teresa_a_beyers.jpg",
    "scrapedAt": "2026-05-09T22:25:01.117Z"
}
````

#### 🗂 Key output fields

| Group | Fields |
|---|---|
| **Identifiers** | `type`, `firmId`, `id` (alias), `url` / `profileUrl`, `scrapedAt` |
| **Firm** | `name`, `legalName`, `description` (full), `bioSummary` (first sentence), `image`, `numberOfEmployees` |
| **Contact** | `telephone` (formatted), `primaryPhone` (digits-only 10-digit form), `address` (composed), `streetAddress`, `addressLocality` / `city`, `addressRegion` / `state`, `postalCode`, `addressCountry`, `coordinates.{latitude,longitude}` |
| **Practice** | `practiceAreas[]` (e.g. `["Family Law", "Divorce", "Custody"]`), `areaServed[]` (e.g. `["California"]`) |
| **Offices** | `locations[].{name, streetAddress, addressLocality, addressRegion, postalCode, addressCountry, telephone, profileUrl}` — main + every branch office |
| **Attorneys** | `employees[].{name, jobTitle, profileUrl, image}` — every attorney at the firm with their individual FindLaw profile URL |
| **Web presence** | `website` (first non-social URL), `linkedin` (LinkedIn URL if present), `sameAs[]` (full outbound link list) |
| **Commercials** | `priceRange` (e.g. `"$200-400 per hour"` or `"Varies based on case specifics"`), `currenciesAccepted` |

#### ❓ FAQ

**Which FindLaw URLs are supported?**
Listing URLs at every level (`/{practice-area}/{state}/{city}/`, `/{practice-area}/{state}/`, `/{practice-area}/`, `/{state}/`) and direct firm/attorney profile URLs (`/{state}/{city}/{firm-slug}-{base64-id}/`). FindLaw articles, Q\&A, and the Marketing Solutions site are skipped.

**Do I have to paste a URL or can I just pick from dropdowns?**
Either works, but **URLs take strict precedence**. If `startUrls` has any entry, the dropdowns are completely ignored (a warning is printed in the run log). To use the dropdowns, leave `startUrls` empty.

**Why is this a "firm" scraper, not an "attorney" scraper?**
FindLaw's listings + JSON-LD are firm-centric (`LegalService` schema). Each row is one firm/profile with attorneys nested in `employees[]`. If you want one row per attorney, walk the `employees[].profileUrl` URLs in a follow-up run.

**What's `locations[]` vs `address` / `streetAddress`?**
The top-level `address`/`streetAddress` is the firm's primary office. `locations[]` carries every office (including the primary one as `locations[0]`). For multi-office firms, `locations[]` is where the satellite offices are.

**When should I enable `liteMode`?**
Enable for cheap, large-scale lead-gen runs where you only need name + phone + city/state. One listing fetch yields ~30 rows (~30× faster and cheaper than full mode). Disable for CRM enrichment, market intelligence, or any workflow that needs the offices/employees/practice areas.

**Why is my run getting blocked?**
FindLaw serves Cloudflare on every page. The scraper's three-stack TLS race (impit + got-scraping + curl-impersonate Chrome 131) handles that without browser automation, but only the curl-impersonate stack reliably gets through. Keep the default `RESIDENTIAL` + `country: US` proxy on; if you turn the proxy off you'll see 403s immediately.

**Can I scrape private pages or recruiter-only views?**
No. The scraper accesses only publicly available firm and attorney profiles — no logged-in content, no FindLaw Pro / advertising-only features.

**How do I limit results?**
Set `maxItems`. The actor stops queuing new firms as soon as the cap is reached.

#### 💬 Support

- For issues or feature requests, please use the **Issues** tab on the actor's Apify Console page.
- Author's website: <https://muhamed-didovic.github.io/>
- Email: <muhamed.didovic@gmail.com>

#### 🛠 Additional services

- Custom output shape, additional fields, or one-off datasets: <muhamed.didovic@gmail.com>
- Need a similar scraper for another legal directory (Avvo, Justia, Martindale, Lawyers.com, Super Lawyers)? Drop an email — Avvo is already shipped.
- For API access (no Apify fee, just a usage fee for the API): <muhamed.didovic@gmail.com>

#### 🔎 Explore more scrapers

If this FindLaw Scraper was useful, see other scrapers and actors at [memo23's Apify profile](https://apify.com/memo23) — covering job boards, real estate, social media, and more. (Avvo lawyer directory scraper also available.)

***

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by FindLaw, Thomson Reuters, or any of their subsidiaries or affiliates. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available firm and attorney profile pages on lawyers.findlaw.com — no authenticated endpoints, no FindLaw Pro / advertising-only features, no content behind a logged-in session. Users are responsible for ensuring their use complies with lawyers.findlaw.com's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any state-bar rules around the marketing or use of attorney data in their jurisdiction.

***

### SEO Keywords

findlaw scraper, scrape findlaw, findlaw api, lawyers.findlaw.com scraper, Apify findlaw, us law firm directory scraper, law firm directory api, attorney directory scraper, lawyer leads scraper, legal marketing leads, attorney contact data, lawyer contact info scraper, us law firm database, law firm search api, legal directory scraper, legal vertical lead generation, avvo alternative scraper, justia alternative scraper, martindale alternative scraper, super lawyers alternative scraper, lawyers.com alternative scraper, attorney email scraper, law firm leads, solo practitioner data, small law firm leads, law firm practice areas data, law firm geo coordinates, multi-office law firm data, law firm employee roster, attorney roster scraper, law firm pricing data

# Actor input Schema

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

Paste any lawyers.findlaw.com URL — listing pages (`/{practice-area}/{state}/{city}/`) and direct firm/attorney URLs (`/{state}/{city}/{firm-slug}-{base64-id}/`) are auto-classified. Takes precedence over the practice-area / state / city dropdowns below — clear this list to use the dropdowns.

## `searchByCategory` (type: `array`):

Select one or more practice areas. Combined with U.S. states + optional cities below as a cartesian product (e.g. 2 areas × 3 states × 2 cities = 12 listing URLs). ⚠️ Ignored when the FindLaw URLs field above is non-empty.

## `searchByLocation` (type: `array`):

Select one or more U.S. states (full state names as slugs). Combined with practice areas above as a cartesian product. Empty = national listings (one per practice area). ⚠️ Ignored when the FindLaw URLs field is non-empty.

## `searchByCity` (type: `array`):

Optional city slugs (e.g. `los-angeles`, `san-francisco`, `new-york`). When set, narrows the listing URL to `/{practice-area}/{state}/{city}/`. Cities must be valid for the chosen state(s); FindLaw uses lowercase-hyphenated city names. ⚠️ Ignored when the FindLaw URLs field is non-empty.

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

Hard cap on the number of firm/attorney profiles collected across all listings. FindLaw listings paginate ~30 per page; the scraper follows pagination automatically until this cap is hit.

## `liteMode` (type: `boolean`):

When enabled, the scraper skips per-firm detail fetches and emits one row per card directly from the listing's JSON-LD `LegalService` items. ~30× faster and ~30× cheaper (one listing fetch yields ~30 rows). Trade-off: rows have name + telephone + image + city/state/country only — no full address, no geo coordinates, no employees, no multiple offices, no website, no practice areas, no description.

## `maxConcurrency` (type: `integer`):

Maximum number of firm detail pages processed in parallel.

## `minConcurrency` (type: `integer`):

Minimum number of firm detail pages processed in parallel.

## `maxRequestRetries` (type: `integer`):

Number of retries before a failed request is given up.

## `proxy` (type: `object`):

Apify proxy settings. FindLaw serves Cloudflare on listing + detail pages — a US residential pool is strongly recommended.

## Actor input object example

```json
{
  "startUrls": [
    "https://lawyers.findlaw.com/family-law/california/los-angeles/"
  ],
  "searchByCategory": [
    "family-law"
  ],
  "searchByLocation": [
    "california"
  ],
  "searchByCity": [
    "los-angeles"
  ],
  "maxItems": 1000,
  "liteMode": false,
  "maxConcurrency": 10,
  "minConcurrency": 1,
  "maxRequestRetries": 5,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# 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 = {
    "startUrls": [
        "https://lawyers.findlaw.com/family-law/california/los-angeles/"
    ],
    "searchByCategory": [
        "family-law"
    ],
    "searchByLocation": [
        "california"
    ],
    "searchByCity": [
        "los-angeles"
    ],
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/findlaw-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 = {
    "startUrls": ["https://lawyers.findlaw.com/family-law/california/los-angeles/"],
    "searchByCategory": ["family-law"],
    "searchByLocation": ["california"],
    "searchByCity": ["los-angeles"],
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/findlaw-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 '{
  "startUrls": [
    "https://lawyers.findlaw.com/family-law/california/los-angeles/"
  ],
  "searchByCategory": [
    "family-law"
  ],
  "searchByLocation": [
    "california"
  ],
  "searchByCity": [
    "los-angeles"
  ],
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call memo23/findlaw-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "FindLaw.com Lawyer Directory Scraper",
        "description": "Scrape lawyers.findlaw.com — one row per firm with every office address (lat/long), every attorney on staff, practice areas, website, and price range. Multi-select practice × state × city, or paste any FindLaw URL. JSON/CSV, billed per result.",
        "version": "0.0",
        "x-build-id": "hqW4r8MUIrsCD5Rhe"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/memo23~findlaw-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-memo23-findlaw-scraper",
                "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/memo23~findlaw-scraper/runs": {
            "post": {
                "operationId": "runs-sync-memo23-findlaw-scraper",
                "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/memo23~findlaw-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-memo23-findlaw-scraper",
                "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": {
                    "startUrls": {
                        "title": "FindLaw URLs",
                        "type": "array",
                        "description": "Paste any lawyers.findlaw.com URL — listing pages (`/{practice-area}/{state}/{city}/`) and direct firm/attorney URLs (`/{state}/{city}/{firm-slug}-{base64-id}/`) are auto-classified. Takes precedence over the practice-area / state / city dropdowns below — clear this list to use the dropdowns.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "searchByCategory": {
                        "title": "Practice areas",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Select one or more practice areas. Combined with U.S. states + optional cities below as a cartesian product (e.g. 2 areas × 3 states × 2 cities = 12 listing URLs). ⚠️ Ignored when the FindLaw URLs field above is non-empty.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "brain-injury",
                                "business-commercial-law",
                                "collaborative-law",
                                "criminal-law",
                                "custody-visitation",
                                "divorce",
                                "drug-crime",
                                "dui-dwi",
                                "education-law",
                                "elder-law",
                                "employment-law-employee",
                                "estate-planning",
                                "family-law",
                                "immigration-naturalization-law",
                                "litigation-appeals",
                                "medical-malpractice",
                                "motor-vehicle-accidents-plaintiff",
                                "nursing-home-abuse",
                                "personal-injury-plaintiff",
                                "probate-estate-administration",
                                "real-estate-law",
                                "sex-crime",
                                "sexual-harassment",
                                "social-security-disability",
                                "taxation-law",
                                "traffic-violations",
                                "trusts",
                                "wills",
                                "workers-compensation-law",
                                "wrongful-death-plaintiff",
                                "wrongful-termination"
                            ],
                            "enumTitles": [
                                "Brain Injury",
                                "Business / Commercial Law",
                                "Collaborative Law",
                                "Criminal Law",
                                "Custody / Visitation",
                                "Divorce",
                                "Drug Crime",
                                "DUI / DWI",
                                "Education Law",
                                "Elder Law",
                                "Employment Law (employee)",
                                "Estate Planning",
                                "Family Law",
                                "Immigration / Naturalization",
                                "Litigation / Appeals",
                                "Medical Malpractice",
                                "Motor-Vehicle Accidents (plaintiff)",
                                "Nursing-Home Abuse",
                                "Personal Injury (plaintiff)",
                                "Probate / Estate Administration",
                                "Real Estate Law",
                                "Sex Crime",
                                "Sexual Harassment",
                                "Social Security Disability",
                                "Taxation Law",
                                "Traffic Violations",
                                "Trusts",
                                "Wills",
                                "Workers Compensation",
                                "Wrongful Death (plaintiff)",
                                "Wrongful Termination"
                            ]
                        }
                    },
                    "searchByLocation": {
                        "title": "U.S. states",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Select one or more U.S. states (full state names as slugs). Combined with practice areas above as a cartesian product. Empty = national listings (one per practice area). ⚠️ Ignored when the FindLaw URLs field is non-empty.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "alabama",
                                "alaska",
                                "arizona",
                                "arkansas",
                                "california",
                                "colorado",
                                "connecticut",
                                "delaware",
                                "district-of-columbia",
                                "florida",
                                "georgia",
                                "hawaii",
                                "idaho",
                                "illinois",
                                "indiana",
                                "iowa",
                                "kansas",
                                "kentucky",
                                "louisiana",
                                "maine",
                                "maryland",
                                "massachusetts",
                                "michigan",
                                "minnesota",
                                "mississippi",
                                "missouri",
                                "montana",
                                "nebraska",
                                "nevada",
                                "new-hampshire",
                                "new-jersey",
                                "new-mexico",
                                "new-york",
                                "north-carolina",
                                "north-dakota",
                                "ohio",
                                "oklahoma",
                                "oregon",
                                "pennsylvania",
                                "rhode-island",
                                "south-carolina",
                                "south-dakota",
                                "tennessee",
                                "texas",
                                "utah",
                                "vermont",
                                "virginia",
                                "washington",
                                "west-virginia",
                                "wisconsin",
                                "wyoming"
                            ],
                            "enumTitles": [
                                "Alabama",
                                "Alaska",
                                "Arizona",
                                "Arkansas",
                                "California",
                                "Colorado",
                                "Connecticut",
                                "Delaware",
                                "Dist. of Columbia",
                                "Florida",
                                "Georgia",
                                "Hawaii",
                                "Idaho",
                                "Illinois",
                                "Indiana",
                                "Iowa",
                                "Kansas",
                                "Kentucky",
                                "Louisiana",
                                "Maine",
                                "Maryland",
                                "Massachusetts",
                                "Michigan",
                                "Minnesota",
                                "Mississippi",
                                "Missouri",
                                "Montana",
                                "Nebraska",
                                "Nevada",
                                "New Hampshire",
                                "New Jersey",
                                "New Mexico",
                                "New York",
                                "North Carolina",
                                "North Dakota",
                                "Ohio",
                                "Oklahoma",
                                "Oregon",
                                "Pennsylvania",
                                "Rhode Island",
                                "South Carolina",
                                "South Dakota",
                                "Tennessee",
                                "Texas",
                                "Utah",
                                "Vermont",
                                "Virginia",
                                "Washington",
                                "West Virginia",
                                "Wisconsin",
                                "Wyoming"
                            ]
                        }
                    },
                    "searchByCity": {
                        "title": "Cities (optional)",
                        "type": "array",
                        "description": "Optional city slugs (e.g. `los-angeles`, `san-francisco`, `new-york`). When set, narrows the listing URL to `/{practice-area}/{state}/{city}/`. Cities must be valid for the chosen state(s); FindLaw uses lowercase-hyphenated city names. ⚠️ Ignored when the FindLaw URLs field is non-empty.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxItems": {
                        "title": "Max items",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Hard cap on the number of firm/attorney profiles collected across all listings. FindLaw listings paginate ~30 per page; the scraper follows pagination automatically until this cap is hit.",
                        "default": 1000
                    },
                    "liteMode": {
                        "title": "Lite mode (~30× faster, ~30× cheaper — name + phone + city/state only)",
                        "type": "boolean",
                        "description": "When enabled, the scraper skips per-firm detail fetches and emits one row per card directly from the listing's JSON-LD `LegalService` items. ~30× faster and ~30× cheaper (one listing fetch yields ~30 rows). Trade-off: rows have name + telephone + image + city/state/country only — no full address, no geo coordinates, no employees, no multiple offices, no website, no practice areas, no description.",
                        "default": false
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum number of firm detail pages processed in parallel.",
                        "default": 10
                    },
                    "minConcurrency": {
                        "title": "Min concurrency",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Minimum number of firm detail pages processed in parallel.",
                        "default": 1
                    },
                    "maxRequestRetries": {
                        "title": "Max request retries",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Number of retries before a failed request is given up.",
                        "default": 5
                    },
                    "proxy": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify proxy settings. FindLaw serves Cloudflare on listing + detail pages — a US residential pool is strongly recommended.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ],
                            "apifyProxyCountry": "US"
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
