# State Bar \[$1💰] Lawyer & Attorney License Verification (`memo23/us-state-bar-scraper`) Actor

💰$1 per 1,000 results. Verify US attorneys against their state bar's official roster. Look up name, license status (Active/Inactive/Resigned/Disbarred), bar #, city, admission date — sourced directly from the state bar. v1: California (~250k attorneys). 14 filters. JSON/CSV out, billed per result.

- **URL**: https://apify.com/memo23/us-state-bar-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Automation, Agents, Lead generation
- **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

## US State Bar Attorney Search Scraper

**Verify and search any US state bar's licensee directory.** Look up attorneys by name, firm, city, or zip — get back a normalized record with bar number, name (split into first/middle/last), license status (Active / Inactive / Resigned / Disbarred / Suspended / Deceased / Not Eligible), city, admission date (ISO + raw), and a direct link to the official state-bar profile page. JSON or CSV out, billed per result.

> 🚧 **v1: California (CA) only.** State bar websites are deeply different from each other (form fields, result HTML, status vocab) so each state ships as a per-state adapter module. California is the largest market (~250k licensed attorneys); more states are added incrementally. Request a state via the support email if you need it prioritized.

#### How it works

![How US State Bar Scraper works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-state-bar.png)

#### 🚀 Quick start

The actor is **prefilled with a working demo** (`state: CA`, `freeText: Smith`). Just click **Start** — you'll get the first 100 California-bar attorneys named Smith, with status, city, and admission date for each. Then narrow with the filters below.

**Three search modes** (pick one — they don't combine):

| Mode | When to use | Example input |
|---|---|---|
| **A. Free-text name search** | "Find any attorney named X" | `freeText: "Smith"` |
| **B. Multi-filter search** | "All Active Family Law attorneys in Berkeley who speak Mandarin" | `practiceArea: "Family Law"` + `city: "Berkeley"` + `languageSpoken: "Mandarin"` |
| **C. Bar number lookup** | "Verify this specific attorney" | `barNumber: "200000"` (returns name + bar ## only — degraded) |

**Three example queries to try:**

```jsonc
// 1. License verification — "Is this attorney a CA bar member?"
{ "state": "CA", "freeText": "Joanna Lynn Grisinger" }

// 2. Lead-gen — "All Active Family Law attorneys in Alameda County"
{ "state": "CA", "practiceArea": "29", "county": "AL" }
//   29 = Family Law,  AL = Alameda County

// 3. Niche outreach — "Mandarin-speaking certified Family Law specialists"
{ "state": "CA", "legalSpecialty": "04", "languageSpoken": "2" }
//   04 = Family Law (certified),  2 = Mandarin
````

> 💡 **Tip:** California's search returns **at most 500 rows per query** with no pagination. If your filter is too broad and you hit 500, narrow it (add a city or practice area). Two filters combined typically lands well under the cap.

#### ✨ Why use this scraper?

License verification, compliance audits, attorney lead lists, "is this lawyer real" lookups — anything where you need authoritative state-bar registration data.

- 🏛 **Public license records, not marketing data.** Sourced directly from each state bar's official licensee directory — same data the bar publishes for public use. Status, admission date, and bar number are authoritative.
- 🎯 **Two search modes per state.** California (v1) supports both QuickSearch (free-text name) and AdvancedSearch (separate last/first/middle name + match-mode + firm + city + state + zip). Pick the one that fits your query.
- ✅ **Normalized status enum.** Each state bar uses different status vocabulary ("Eligible" vs "Active" vs "Good Standing"); we normalize to a single 8-value enum (`active` / `inactive` / `resigned` / `disbarred` / `suspended` / `deceased` / `not_eligible` / `other`) so cross-state filters work cleanly. The original raw string is also preserved on every row.
- 📅 **Admission date as both ISO and raw.** `admissionDate: "2014-10-01"` (ISO) plus `admissionDateRaw: "October 2014"` (the bar's own format) — pick whichever your downstream system needs.
- 🧱 **Adapter-per-state architecture.** Each state's quirks live in its own module (`src/states/{code}.ts`). The output schema is universal — adding a new state doesn't break existing rows.
- 🚫 **No browser automation, no paid CF clearance.** Search-results pages are server-rendered HTML on every supported state. We use the same impit + 3-stack TLS race the rest of our scrapers use, but most state bars don't even need it.
- 📤 **Clean exports.** One row per attorney. JSON + CSV exported automatically.

#### 🎯 Use cases

| Team | What they build |
|------|-----------------|
| **Compliance & vendor management** | "Is this lawyer actively licensed in CA?" — one query, one row, returns status + admission date |
| **Lead-gen / outreach** | Bulk search by city or last-name prefix — get every Active CA attorney in San Francisco named Smith |
| **CRM enrichment** | Patch an existing attorney CRM with verified bar #, name split, and current status |
| **Legal-tech research** | Density maps of active attorneys by city, status distribution analyses |
| **Recruiting** | Find attorneys by admission date (e.g. "all attorneys admitted to the CA bar between 2018 and 2020") via post-filtering on `admissionDate` |
| **Bar verification audits** | Cross-check that attorneys claiming a CA license are actually registered |

#### 📥 Inputs

##### State (required)

Pick one US state from the dropdown. The actor dispatches to the matching adapter.

- **California (CA)** ✅ — supported in v1

##### Search filters

Supply at least one of the filters below. The adapter only honors filters its backend supports — others are silently dropped (so the same input shape works for every state once more are added).

| Filter | CA | Notes |
|---|---|---|
| `barNumber` | ✅ ⚠️ | Look up a single attorney by their CA bar registration number. **Returns a degraded row** (name + bar ## only) — see caveat below. |
| `freeText` | ✅ | Maps to CA QuickSearch (free-text across attorney names). The simplest entry point. |
| `lastName` | ✅ | Maps to CA AdvancedSearch — combined with `soundsLike` for match-mode (off = begins-with, on = sounds-like). |
| `firstName` | ✅ | Same. |
| `middleName` | ✅ | Same. |
| `firmName` | ✅ | CA AdvancedSearch firm-name filter. |
| `city` | ✅ | Filter by registered office city. |
| `addressState` | ✅ | 2-letter state code on the *registered address* (lets you find CA-licensed attorneys whose office is in another state). |
| `zip` | ✅ | 5-digit US zip. |
| `soundsLike` | ✅ | Toggle phonetic / sounds-like match-mode for name fields. |
| `district` | ✅ | California State Bar district (1-6 + Outside California). 8 enum options. |
| `county` | ✅ | California county code (60 enum options including "Statewide" and "Non-California"). |
| `legalSpecialty` | ✅ | Certified legal specialty (22 enum options — Bankruptcy Law, Family Law, Criminal Trial Advocacy, etc.). |
| `languageSpoken` | ✅ | Language spoken by the attorney (99 enum options — Mandarin, Spanish, ASL, Arabic, etc.). |
| `practiceArea` | ✅ | Practice area (66 enum options — broader than certified specialties). |

> ⚠️ **Bar-number lookup is a degraded path on CA.** California's `apps.calbar.ca.gov/attorney/Licensee/Detail/{n}` page is a JavaScript-rendered Drupal SPA. The `<title>` is server-rendered (`{name} ## {barNum}`), so we can extract a row with **name + bar number + profileUrl only** — no status, city, or admission date. For full data on a known attorney, search by `lastName` + `firstName` instead and pick the matching row. Invalid bar numbers (e.g. "1" or unassigned IDs) are returned as zero rows.

#### 🔄 How it works (technical)

1. **Resolve adapter.** The `state` field selects one of the per-state adapter modules. Each adapter knows that state's URL patterns, form fields, result HTML, and status vocab.
2. **Compose search URL.** Adapter takes the supplied filters and builds either a QuickSearch (single free-text param) or AdvancedSearch (full 13-field form) URL — whichever matches the filters present.
3. **Fetch the search-results page** through impit, with the parallel 3-stack race (impit + got-scraping + curl-impersonate) as fallback if the soft anti-bot trips.
4. **Parse the SSR'd table** with cheerio — anchored on column headers (`Name | Status | Number | City | Admission Date`) so we don't pick up the search-form table by accident.
5. **Normalize each row** — split the `Last, First Middle` name format, normalize the status enum, parse the admission date to ISO.
6. **Push one row per attorney** to the dataset.

#### ⚙️ Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `state` | string (enum) | `"CA"` | Two-letter state code. v1 supports `CA` only; more states added incrementally. |
| `barNumber` | string | — | Bar ## lookup (returns 1 degraded row — see caveat above). |
| `freeText` | string | — | Free-text search (typically a name). Maps to CA QuickSearch. |
| `lastName` | string | — | Last-name filter (CA AdvancedSearch). |
| `firstName` | string | — | First-name filter. |
| `middleName` | string | — | Middle-name filter. |
| `firmName` | string | — | Firm-name filter. |
| `city` | string | — | Registered office city. |
| `addressState` | string | — | 2-letter US state on the registered address (out-of-state members). |
| `zip` | string | — | 5-digit US zip. |
| `soundsLike` | boolean | `false` | Toggle phonetic match-mode. |
| `district` | string (enum) | — | California State Bar district (1-6 + Outside California). |
| `county` | string (enum) | — | California county (60 options). |
| `legalSpecialty` | string (enum) | — | Certified legal specialty (22 options). |
| `languageSpoken` | string (enum) | — | Language spoken (99 options). |
| `practiceArea` | string (enum) | — | Practice area (66 options). |
| `maxItems` | integer | `1000` | Hard cap on rows. CA's search caps at 500 results per query (no pagination available) — combine multiple filters to narrow if you need more. |
| `maxConcurrency` / `minConcurrency` | integer | `5` / `1` | Parallel HTTP request limits. |
| `maxRequestRetries` | integer | `5` | Retries before a failed request is given up. |
| `proxy` | object | Apify residential, US | Most state bars don't have aggressive anti-bot, so a small US-residential pool is plenty. |

#### 📦 Output sample

One row per attorney:

```json
{
    "state": "CA",
    "barNumber": "298556",
    "name": "Smith, Alan Patrick",
    "firstName": "Alan",
    "middleName": "Patrick",
    "lastName": "Smith",
    "statusRaw": "Active",
    "status": "active",
    "city": "San Francisco",
    "addressState": "CA",
    "admissionDate": "2014-10-01",
    "admissionDateRaw": "October 2014",
    "profileUrl": "https://apps.calbar.ca.gov/attorney/Licensee/Detail/298556",
    "scrapedAt": "2026-05-09T23:32:01.117Z"
}
```

#### 🗂 Output fields

| Group | Fields |
|---|---|
| **Identifiers** | `state` (2-letter), `barNumber`, `profileUrl`, `scrapedAt` |
| **Person** | `name` (Last, First Middle as the bar formats it), `firstName`, `middleName`, `lastName` |
| **Licensing** | `status` (normalized: `active` / `inactive` / `resigned` / `disbarred` / `suspended` / `deceased` / `not_eligible` / `other`), `statusRaw` (the bar's original string), `admissionDate` (ISO yyyy-mm-dd), `admissionDateRaw` (e.g. `"October 2014"`) |
| **Location** | `city`, `addressState` |

#### ❓ FAQ

**Which states are supported?**
v1 ships California (CA) only. State bar websites are independently built — each is a custom adapter module. More states are added incrementally as demand justifies the work. Request a state via the support email below if you need it.

**Why is the actor "California-only" if it claims to be a "US State Bar" scraper?**
The architecture supports any US state — adding a new state is a new module file, not a rewrite. We ship CA first because it's the largest market (~250k attorneys, biggest demand) and clean to scrape. As we add more states, the same actor (and the same input shape) supports them with no changes for existing customers.

**Can I look up an attorney by their bar number?**
Yes, on California — set `barNumber` and the actor fetches the detail page and extracts the attorney's name from the server-rendered `<title>` tag. **It's a degraded row** (name + bar ## + profileUrl only — no status, city, or admission date) because the rest of the detail page is JavaScript-rendered. For full data on a known attorney, search by their name instead and pick the matching row from the results.

**What's the difference between `legalSpecialty` and `practiceArea`?**
California maintains two parallel taxonomies. **`legalSpecialty`** (22 options) lists *certified* specialties — formal credentials granted by the State Bar (e.g. "Family Law", "Bankruptcy Law", "Criminal Trial Advocacy\*"). Asterisk-marked entries are sub-specialties. **`practiceArea`** (66 options) is a broader self-reported categorization that any attorney can claim (e.g. "Real Estate", "Internet Law", "Class Actions"). Use `legalSpecialty` for credentialed search; `practiceArea` for everyday "what does this lawyer do" search.

**Can I combine multiple filters?**
Yes — and you should. Single broad filters (e.g. just `practiceArea=Family Law`) will hit the 500-row cap. Combine 2-3 filters (e.g. `practiceArea=Family Law` + `county=Alameda` + `languageSpoken=Mandarin`) to narrow into a useful subset.

**What's the difference between QuickSearch and AdvancedSearch on CA?**
QuickSearch has one input (free-text name search). AdvancedSearch has 17 fields (separate last/first/middle name with match-mode, firm, city/state/zip, district, county, language, practice area, certified specialty). The adapter picks QuickSearch when only `freeText` is set, and AdvancedSearch when any fine-grained filter is present.

**What's `status: "active"` vs `statusRaw: "Active"`?**
Different states use different status vocab — California uses `Active` / `Inactive` / `Resigned` / `Disbarred` / `Suspended` / `Deceased` / `Not Eligible`, but other states use `Eligible` or `Good Standing`. The normalized `status` enum gives you a stable key for cross-state filtering; `statusRaw` preserves the original string from the source.

**How are CA's status values mapped?**

- `Active` → `active`
- `Inactive` → `inactive`
- `Resigned` → `resigned`
- `Disbarred` → `disbarred`
- `Suspended` → `suspended`
- `Deceased` → `deceased`
- `Not Eligible` → `not_eligible`
- Anything else → `other` (preserve the raw string for inspection)

**How accurate is the admission date?**
California's bar publishes it as month + year (e.g. "October 2014"); we normalize to the first of the month (`2014-10-01`). The `admissionDateRaw` field preserves the original string in case you need exact source fidelity.

**Why does the search cap at 500 results on CA?**
California's QuickSearch and AdvancedSearch both cap at 500 result rows server-side. If a query produces more matches, you'll see the first 500 — narrow your filters (add a city, use `lastName` instead of `freeText`, etc.) to get the rest.

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

#### 💬 Support

- For issues, feature requests, or to request a new state — 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 specific state added urgently? Drop an email — most non-Cloudflare-protected state bars take a half day each.
- For API access (no Apify fee, just a usage fee for the API): <muhamed.didovic@gmail.com>

#### 🔎 Explore more scrapers

Other legal-vertical scrapers at [memo23's Apify profile](https://apify.com/memo23) — Avvo (lawyer directory) and FindLaw (law-firm directory) are already shipped.

***

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by The State Bar of California, the American Bar Association, any other state bar association, or any of their subsidiaries or affiliates. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available licensee directory pages — the same pages each state bar publishes for public license-verification use. No authenticated endpoints, no member-only features, no content behind a logged-in session. Users are responsible for ensuring their use complies with each state bar's terms of service, applicable data-protection law (GDPR, CCPA, etc.), and any rules around the use of attorney licensing data in their jurisdiction.

This actor is intended for license verification, compliance, lead-generation, and research purposes. The data it returns is **public record**.

***

### SEO Keywords

us state bar scraper, state bar attorney search, california state bar scraper, calbar scraper, california attorney lookup, attorney license verification, attorney status check, lawyer license check api, bar number lookup, attorney licensee search, us attorney public records, lawyer compliance check, attorney verification, license verification scraper, lawyer directory scraper, attorney directory api, scrape calbar, scrape state bar, lawyer status check api, attorney admission date data, lawyer disciplinary check, attorney bar registration scraper, public attorney records, california bar attorney lookup, lawyer compliance api, legal vendor verification, attorney lead generation

# Actor input Schema

## `state` (type: `string`):

Which state bar to search. Each state has its own search backend with different supported filters; the actor dispatches to the matching adapter. More states are added incrementally — request a state via the support email if it's not yet listed.

## `barNumber` (type: `string`):

Look up a single attorney by their California State Bar registration number (example: `200000` returns attorney Joanna Lynn Grisinger). ⚠️ **Degraded path**: returns a row with name + bar # + profile URL only — no status, city, or admission date. California's detail page is JS-rendered, so we extract only what's in the server-rendered `<title>` tag. For full data, search by name instead.

## `freeText` (type: `string`):

Free-text name search. The simplest entry point — works for partial or full names. Examples: `Smith`, `Garcia`, `Aaron Smith`. On California this maps to the QuickSearch FreeText field. ⚠️ Doesn't accept bar numbers — use the Bar number field for that.

## `lastName` (type: `string`):

Last-name filter (example: `Smith`, `Chen`, `O'Connor`). Combined with the **Sounds-like** toggle: off (default) → begins-with match; on → phonetic match (e.g. "Smith" also matches "Smyth").

## `firstName` (type: `string`):

First-name filter (example: `Aaron`, `Maria`). Same match-mode rule as last name.

## `middleName` (type: `string`):

Middle-name filter (example: `Patrick`).

## `firmName` (type: `string`):

Firm-name filter (example: `Latham & Watkins` or just `Latham`).

## `city` (type: `string`):

Registered office city (example: `Los Angeles`, `San Francisco`, `Berkeley`).

## `addressState` (type: `string`):

2-letter US state code on the attorney's *registered address* (example: `NY`, `TX`). Useful for finding California-licensed attorneys whose office is registered out-of-state.

## `zip` (type: `string`):

5-digit US zip code (example: `94612`, `90012`).

## `soundsLike` (type: `boolean`):

When enabled, the state adapter switches its name match-mode to a phonetic / sounds-like match (e.g. "Smith" also matches "Smyth"). Off by default (begin-with match).

## `district` (type: `string`):

California State Bar district (example: `District 5` for Los Angeles area). 8 options.

## `county` (type: `string`):

California county (example: `Los Angeles`, `San Francisco`, `Alameda`). 60 options including "Statewide" and "Non-California".

## `legalSpecialty` (type: `string`):

Certified legal specialty — formal credentials granted by the State Bar (example: `Family Law`, `Bankruptcy Law`, `Criminal Trial Advocacy*`). 22 options. Asterisk-marked entries are sub-specialties. Use this for credentialed-attorney search.

## `languageSpoken` (type: `string`):

Language the attorney speaks (example: `Mandarin`, `Spanish`, `American Sign Language (ASL)`, `Arabic`). 99 options. Useful for finding multilingual attorneys for non-English-speaking clients.

## `practiceArea` (type: `string`):

Practice area — broader self-reported categorization (example: `Real Estate`, `Family Law`, `Internet Law`). 66 options. Use this for everyday "what does this lawyer do" search; use Certified legal specialty above for credentialed search.

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

Hard cap on rows. ⚠️ California's search caps at 500 results per query (no pagination is available). If a query returns 500, you've hit the cap — narrow your filters to get a different subset. Default 1000 lets the actor consume any single query without throttling.

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

Maximum number of pages processed in parallel.

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

Minimum number of pages processed in parallel.

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

Number of retries before a failed request is given up.

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

Apify proxy settings. Most state bars don't have aggressive anti-bot — a small US-residential pool is plenty.

## Actor input object example

```json
{
  "state": "CA",
  "freeText": "Smith",
  "soundsLike": false,
  "district": "",
  "county": "",
  "legalSpecialty": "",
  "languageSpoken": "",
  "practiceArea": "",
  "maxItems": 1000,
  "maxConcurrency": 5,
  "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 = {
    "state": "CA",
    "freeText": "Smith",
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/us-state-bar-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 = {
    "state": "CA",
    "freeText": "Smith",
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/us-state-bar-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 '{
  "state": "CA",
  "freeText": "Smith",
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call memo23/us-state-bar-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "State Bar [$1💰] Lawyer & Attorney License Verification",
        "description": "💰$1 per 1,000 results. Verify US attorneys against their state bar's official roster. Look up name, license status (Active/Inactive/Resigned/Disbarred), bar #, city, admission date — sourced directly from the state bar. v1: California (~250k attorneys). 14 filters. JSON/CSV out, billed per result.",
        "version": "0.0",
        "x-build-id": "siyj5ANJm7vLjNe3l"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/memo23~us-state-bar-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-memo23-us-state-bar-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~us-state-bar-scraper/runs": {
            "post": {
                "operationId": "runs-sync-memo23-us-state-bar-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~us-state-bar-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-memo23-us-state-bar-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": {
                    "state": {
                        "title": "State",
                        "enum": [
                            "CA"
                        ],
                        "type": "string",
                        "description": "Which state bar to search. Each state has its own search backend with different supported filters; the actor dispatches to the matching adapter. More states are added incrementally — request a state via the support email if it's not yet listed."
                    },
                    "barNumber": {
                        "title": "Bar number",
                        "type": "string",
                        "description": "Look up a single attorney by their California State Bar registration number (example: `200000` returns attorney Joanna Lynn Grisinger). ⚠️ **Degraded path**: returns a row with name + bar # + profile URL only — no status, city, or admission date. California's detail page is JS-rendered, so we extract only what's in the server-rendered `<title>` tag. For full data, search by name instead."
                    },
                    "freeText": {
                        "title": "Free-text query (typically a name)",
                        "type": "string",
                        "description": "Free-text name search. The simplest entry point — works for partial or full names. Examples: `Smith`, `Garcia`, `Aaron Smith`. On California this maps to the QuickSearch FreeText field. ⚠️ Doesn't accept bar numbers — use the Bar number field for that."
                    },
                    "lastName": {
                        "title": "Last name",
                        "type": "string",
                        "description": "Last-name filter (example: `Smith`, `Chen`, `O'Connor`). Combined with the **Sounds-like** toggle: off (default) → begins-with match; on → phonetic match (e.g. \"Smith\" also matches \"Smyth\")."
                    },
                    "firstName": {
                        "title": "First name",
                        "type": "string",
                        "description": "First-name filter (example: `Aaron`, `Maria`). Same match-mode rule as last name."
                    },
                    "middleName": {
                        "title": "Middle name",
                        "type": "string",
                        "description": "Middle-name filter (example: `Patrick`)."
                    },
                    "firmName": {
                        "title": "Firm name",
                        "type": "string",
                        "description": "Firm-name filter (example: `Latham & Watkins` or just `Latham`)."
                    },
                    "city": {
                        "title": "City",
                        "type": "string",
                        "description": "Registered office city (example: `Los Angeles`, `San Francisco`, `Berkeley`)."
                    },
                    "addressState": {
                        "title": "Registered address state (2-letter)",
                        "type": "string",
                        "description": "2-letter US state code on the attorney's *registered address* (example: `NY`, `TX`). Useful for finding California-licensed attorneys whose office is registered out-of-state."
                    },
                    "zip": {
                        "title": "Registered address zip",
                        "type": "string",
                        "description": "5-digit US zip code (example: `94612`, `90012`)."
                    },
                    "soundsLike": {
                        "title": "Sounds-like / phonetic match",
                        "type": "boolean",
                        "description": "When enabled, the state adapter switches its name match-mode to a phonetic / sounds-like match (e.g. \"Smith\" also matches \"Smyth\"). Off by default (begin-with match).",
                        "default": false
                    },
                    "district": {
                        "title": "California district",
                        "enum": [
                            "",
                            "1",
                            "2",
                            "3",
                            "4",
                            "5",
                            "6",
                            "0"
                        ],
                        "type": "string",
                        "description": "California State Bar district (example: `District 5` for Los Angeles area). 8 options.",
                        "default": ""
                    },
                    "county": {
                        "title": "California county",
                        "enum": [
                            "",
                            "**",
                            "ZZ",
                            "AL",
                            "AP",
                            "AM",
                            "BU",
                            "CA",
                            "CO",
                            "CC",
                            "DN",
                            "ED",
                            "FR",
                            "GL",
                            "HM",
                            "IM",
                            "IN",
                            "KN",
                            "KI",
                            "LK",
                            "LS",
                            "LA",
                            "MA",
                            "MR",
                            "MP",
                            "MN",
                            "MC",
                            "MD",
                            "MO",
                            "MT",
                            "NP",
                            "NV",
                            "OR",
                            "PL",
                            "PM",
                            "RV",
                            "SA",
                            "SO",
                            "SR",
                            "SD",
                            "SF",
                            "SJ",
                            "SP",
                            "SM",
                            "SB",
                            "SC",
                            "SZ",
                            "SH",
                            "SI",
                            "SK",
                            "SL",
                            "SN",
                            "ST",
                            "SU",
                            "TE",
                            "TR",
                            "TU",
                            "TL",
                            "VN",
                            "YO",
                            "YU"
                        ],
                        "type": "string",
                        "description": "California county (example: `Los Angeles`, `San Francisco`, `Alameda`). 60 options including \"Statewide\" and \"Non-California\".",
                        "default": ""
                    },
                    "legalSpecialty": {
                        "title": "Certified legal specialty",
                        "enum": [
                            "",
                            "10",
                            "08",
                            "07",
                            "101",
                            "102",
                            "103",
                            "104",
                            "01",
                            "105",
                            "106",
                            "06",
                            "04",
                            "107",
                            "09",
                            "05",
                            "111",
                            "11",
                            "109",
                            "110",
                            "112",
                            "03",
                            "02"
                        ],
                        "type": "string",
                        "description": "Certified legal specialty — formal credentials granted by the State Bar (example: `Family Law`, `Bankruptcy Law`, `Criminal Trial Advocacy*`). 22 options. Asterisk-marked entries are sub-specialties. Use this for credentialed-attorney search.",
                        "default": ""
                    },
                    "languageSpoken": {
                        "title": "Language spoken",
                        "enum": [
                            "",
                            "6",
                            "50",
                            "51",
                            "49",
                            "7",
                            "8",
                            "9",
                            "52",
                            "53",
                            "54",
                            "55",
                            "48",
                            "56",
                            "10",
                            "39",
                            "57",
                            "58",
                            "59",
                            "60",
                            "61",
                            "43",
                            "62",
                            "41",
                            "63",
                            "11",
                            "64",
                            "44",
                            "12",
                            "65",
                            "13",
                            "14",
                            "15",
                            "66",
                            "16",
                            "17",
                            "18",
                            "19",
                            "45",
                            "67",
                            "68",
                            "69",
                            "20",
                            "70",
                            "21",
                            "71",
                            "72",
                            "5",
                            "73",
                            "22",
                            "74",
                            "75",
                            "76",
                            "77",
                            "2",
                            "78",
                            "79",
                            "80",
                            "81",
                            "23",
                            "82",
                            "46",
                            "83",
                            "84",
                            "85",
                            "86",
                            "87",
                            "24",
                            "25",
                            "26",
                            "27",
                            "42",
                            "28",
                            "29",
                            "30",
                            "88",
                            "31",
                            "89",
                            "90",
                            "91",
                            "92",
                            "32",
                            "1",
                            "93",
                            "47",
                            "94",
                            "3",
                            "40",
                            "33",
                            "34",
                            "35",
                            "95",
                            "96",
                            "97",
                            "36",
                            "98",
                            "37",
                            "99",
                            "4",
                            "38"
                        ],
                        "type": "string",
                        "description": "Language the attorney speaks (example: `Mandarin`, `Spanish`, `American Sign Language (ASL)`, `Arabic`). 99 options. Useful for finding multilingual attorneys for non-English-speaking clients.",
                        "default": ""
                    },
                    "practiceArea": {
                        "title": "Practice area",
                        "enum": [
                            "",
                            "1",
                            "2",
                            "3",
                            "4",
                            "5",
                            "6",
                            "7",
                            "8",
                            "9",
                            "10",
                            "11",
                            "12",
                            "13",
                            "14",
                            "15",
                            "16",
                            "17",
                            "18",
                            "19",
                            "20",
                            "21",
                            "22",
                            "23",
                            "24",
                            "25",
                            "26",
                            "27",
                            "28",
                            "29",
                            "30",
                            "31",
                            "32",
                            "33",
                            "65",
                            "34",
                            "35",
                            "36",
                            "37",
                            "38",
                            "39",
                            "40",
                            "41",
                            "42",
                            "66",
                            "43",
                            "44",
                            "45",
                            "46",
                            "47",
                            "48",
                            "49",
                            "50",
                            "51",
                            "52",
                            "53",
                            "54",
                            "55",
                            "56",
                            "57",
                            "58",
                            "59",
                            "60",
                            "61",
                            "62",
                            "63",
                            "64"
                        ],
                        "type": "string",
                        "description": "Practice area — broader self-reported categorization (example: `Real Estate`, `Family Law`, `Internet Law`). 66 options. Use this for everyday \"what does this lawyer do\" search; use Certified legal specialty above for credentialed search.",
                        "default": ""
                    },
                    "maxItems": {
                        "title": "Max items",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Hard cap on rows. ⚠️ California's search caps at 500 results per query (no pagination is available). If a query returns 500, you've hit the cap — narrow your filters to get a different subset. Default 1000 lets the actor consume any single query without throttling.",
                        "default": 1000
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum number of pages processed in parallel.",
                        "default": 5
                    },
                    "minConcurrency": {
                        "title": "Min concurrency",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Minimum number of 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. Most state bars don't have aggressive anti-bot — a small US-residential pool is plenty.",
                        "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
