# California State Bar Attorney Lookup Scraper (`automation-lab/california-state-bar-attorney-lookup`) Actor

Search official California State Bar attorney profiles and export license status, admission, public contact, practice, and discipline information.

- **URL**: https://apify.com/automation-lab/california-state-bar-attorney-lookup.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.66 / 1,000 attorney extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## California State Bar Attorney Lookup Scraper

Search official State Bar of California public attorney profiles by name or bar number and export normalized license, admission, contact, practice, and discipline information. This **California State Bar attorney lookup** Actor turns one-off profile checks into reusable JSON, CSV, Excel, and API-ready records.

Use it to verify a roster before a compliance review, refresh a legal directory, enrich professional records, or preserve a dated snapshot of the information shown on official public profiles.

### What does this Actor do?

The Actor searches the official `apps.calbar.ca.gov` attorney directory.

It supports three lookup routes:

- full or partial attorney names;
- California bar numbers;
- direct official attorney profile URLs.

For each matched profile it fetches the official detail page and returns one typed dataset row. Name searches may match several attorneys; `maxItems` provides a predictable run limit. Duplicate profiles found by more than one input are saved only once.

This Actor does not use third-party lawyer directories, infer a person's standing, or claim that a missing public field exists.

### Who is it for?

**Compliance teams** can confirm current public license status and retain the source URL used for verification.

**Legal-directory operators** can refresh names, organizations, contact details, practice areas, and admission information.

**Recruiting and vendor-risk teams** can check supplied attorney rosters by bar number.

**Data engineers** can schedule recurring Tasks and load normalized records into a warehouse, spreadsheet, CRM, or review queue.

**Researchers** can export bounded name-search results without manually opening each official profile.

### Why use this California attorney lookup?

- Reads the official California State Bar public profile rather than a republished directory.
- Supports both discovery by name and exact bar-number verification.
- Includes the current status plus the published status, disciplinary, and administrative history table.
- Exposes official profile and public discipline/document links for audit trails.
- Produces stable field names across JSON, CSV, Excel, XML, RSS, and API exports.
- Uses direct server-rendered HTML, so no browser or residential proxy is required.
- Applies bounded retries to temporary network, 429, and server errors.

### What data can I extract?

| Field | Meaning |
| --- | --- |
| `barNumber` | State Bar license number from the official profile |
| `fullName` | Published attorney name |
| `licenseStatus` | Current status shown on the profile |
| `admissionDate` | Date of the published admission event, when available |
| `organization` | Organization parsed from the public address, when distinguishable |
| `address` | Full public address text |
| `phone`, `fax`, `email`, `website` | Public contact fields; unavailable values are `null` |
| `lawSchool` | Published law-school text |
| `practiceAreas` | Self-reported practice areas |
| `languages` | Self-reported attorney/staff language text |
| `hasDiscipline` | Whether the profile exposes a discipline entry or case/document link |
| `disciplineLinks` | Relevant public discipline or case links exposed by the profile |
| `licenseHistory` | Dated status, discipline, and administrative-action rows |
| `profileUrl` | Canonical official attorney profile URL |
| `matchedInput` | Name, bar number, or URL that found the profile |
| `retrievedAt` | UTC retrieval timestamp |

The State Bar controls field availability. Nullable contact fields remain `null` rather than being guessed.

### How to get started

1. Open the Actor input page.
2. Enter one or more names, bar numbers, or official profile URLs.
3. Set `maxItems` to the largest number of unique profiles you want.
4. Click **Start**.
5. Open the **Dataset** tab when the run finishes.
6. Export the rows or consume them through the Apify API.

Start with a small exact bar-number lookup when testing an integration.

### Input parameters

#### `names`

An array of full or partial names, up to 50 characters each. The official quick search determines matching behavior. A common surname can return many profiles, so combine it with a conservative `maxItems`.

```json
{
  "names": ["Koichiro Sato"],
  "maxItems": 5
}
```

#### `barNumbers`

An array of one- to six-digit California bar numbers. String values preserve leading zeroes.

```json
{
  "barNumbers": ["344532", "349773"],
  "maxItems": 2
}
```

#### `profileUrls`

Official HTTPS URLs matching `apps.calbar.ca.gov/attorney/Licensee/Detail/<number>`. Other hosts and paths are rejected before network access.

```json
{
  "profileUrls": [
    { "url": "https://apps.calbar.ca.gov/attorney/Licensee/Detail/344532" }
  ],
  "maxItems": 1
}
```

#### `maxItems`

Maximum unique profiles saved across every supplied lookup. Valid values are 1–500; the default is 25.

At least one lookup input is required. A run accepts at most 100 combined names, bar numbers, and URLs.

### Output example

A current official profile produces a record shaped like this:

```json
{
  "barNumber": "344532",
  "fullName": "Koichiro Sato",
  "licenseStatus": "Active",
  "address": "Masuda, Funai, Eifert & Mitchell, Ltd., 19191 S Vermont Ave, Ste 420, Torrance, CA 90502-1051",
  "organization": "Masuda, Funai, Eifert & Mitchell, Ltd.",
  "phone": "310-630-5900",
  "email": null,
  "lawSchool": "Stanford Univ Law School; Stanford CA",
  "practiceAreas": ["Business Law", "Intellectual Property"],
  "admissionDate": "6/10/2022",
  "hasDiscipline": false,
  "disciplineLinks": ["https://www.calbar.ca.gov/public/concerns-about-attorney/recent-disciplinary-actions"],
  "licenseHistory": [
    {
      "date": "Present",
      "licenseStatus": "Active",
      "discipline": null,
      "administrativeAction": null,
      "detailsUrl": null
    }
  ],
  "profileUrl": "https://apps.calbar.ca.gov/attorney/Licensee/Detail/344532",
  "matchedInput": "344532",
  "retrievedAt": "2026-09-05T20:06:57.500Z"
}
```

Output reflects public source content at retrieval time. It is not a legal opinion or independent credential certification.

### How much does it cost to look up California State Bar attorneys?

The Actor uses pay-per-event pricing:

- a small **$0.005 start fee** per run;
- one **attorney** event for each complete profile saved.

At the BRONZE tier, each complete attorney profile costs **$0.006092**. Apify shows the applicable tier and estimated maximum charge before a run. The tier curve is based on measured platform cost and the median of reviewed same-source competitor prices.

You are not charged an attorney event for empty searches, rejected records, duplicate profiles, or failed detail fetches.

### Recurring compliance workflow

Create an Apify Task with a stable list of bar numbers and a bounded `maxItems`.

Schedule it weekly or monthly.

Send each completed dataset to a webhook, spreadsheet, database, or automation flow.

Compare `licenseStatus`, `licenseHistory`, public contact fields, and `retrievedAt` against the prior snapshot in your own system.

The Actor emits current snapshots; it does not itself store historical comparisons or send change alerts.

### Directory enrichment workflow

1. Export bar numbers from the directory you maintain.
2. Pass them in `barNumbers` batches of up to 100 lookup inputs.
3. Join output rows back on `barNumber`.
4. Review nullable or changed public contact data.
5. Preserve `profileUrl` and `retrievedAt` as provenance.

Do not infer that a missing row means an attorney never existed. Confirm unusual cases manually on the official source.

### API usage with cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~california-state-bar-attorney-lookup/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"barNumbers":["344532"],"maxItems":1}'
```

To wait for completion and obtain dataset metadata, use the synchronous Actor run endpoint documented by Apify.

### API usage with JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/california-state-bar-attorney-lookup').call({
  names: ['Koichiro Sato'],
  maxItems: 5,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### API usage with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/california-state-bar-attorney-lookup').call(
    run_input={'barNumbers': ['344532'], 'maxItems': 1}
)
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

Keep API tokens in environment variables or secret stores, not source code.

### Use through MCP

Add the Apify MCP server in Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/california-state-bar-attorney-lookup"
```

Claude Desktop, Cursor, and VS Code setup:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/california-state-bar-attorney-lookup"
    }
  }
}
```

Example prompts:

- “Verify California bar number 344532 and summarize the official status and admission date.”
- “Run these California bar numbers and return a CSV-ready table of status, organization, phone, and profile URL.”
- “Look up Koichiro Sato in the California State Bar and include published license history.”

### Reliability and retry behavior

Each official request has a 45-second timeout.

Temporary network errors, HTTP 429, and server errors receive at most three attempts with bounded backoff. Permanent client errors, unsupported URLs, malformed input, and changed response shapes fail clearly rather than returning a misleading empty success.

The current route uses direct public HTML. There is no hidden residential-proxy fallback, browser cost, or user-configurable proxy mode.

### Limits and source behavior

- The official quick search controls matching and ordering.
- Broad names can expose many results; `maxItems` truncates output deterministically.
- Direct bar-number queries normally resolve to one profile.
- A valid no-result search finishes with zero attorney rows and only the start event.
- Public profiles may omit email, fax, website, organization, language, law-school, practice, or discipline details.
- The State Bar may revise HTML, availability, field labels, or rate limits.
- One run supports at most 100 lookup inputs and 500 emitted profiles.
- Practice areas and languages are self-reported where the profile says so.

### Troubleshooting

#### Why did my name search return several people?

The official quick search supports partial names. Use a fuller name or an exact bar number, and set `maxItems` to the desired bound.

#### Why is a contact field null?

The profile displayed “Not Available” or did not expose the field. The Actor deliberately does not infer private contact information.

#### Why was my profile URL rejected?

Only official HTTPS detail URLs on `apps.calbar.ca.gov` are accepted. Use the canonical URL shown in a result's `profileUrl` field.

#### Why did the run fail instead of returning no rows?

The Actor distinguishes a recognized no-result page from network failures or unrecognized source markup. Inspect the run log; retry later for a temporary upstream failure and report persistent parser errors.

### Responsible use and legal considerations

This Actor accesses public professional-license pages. You remain responsible for complying with the source's terms, applicable privacy and data-protection law, and your organization's retention and review policies.

Use the output for legitimate verification, directory maintenance, research, or integration purposes. Avoid harassment, spam, discriminatory profiling, or decisions based solely on stale automated output.

License status and discipline can have legal significance. Consult the linked official profile and underlying documents, and obtain professional advice where appropriate. The Actor is independent and is not affiliated with or endorsed by the State Bar of California.

### Related Automation Lab Actors

- [Georgia Bar Attorney Directory Scraper](https://apify.com/automation-lab/georgia-bar-attorney-directory-scraper) for official Georgia member records.
- [Pennsylvania Attorney Registry Lookup](https://apify.com/automation-lab/pennsylvania-attorney-registry-lookup) for official Pennsylvania registration and discipline indicators.
- [Arizona State Bar Attorney Scraper](https://apify.com/automation-lab/arizona-state-bar-attorney-scraper) for Arizona professional profiles.

Choose the Actor for the regulator and jurisdiction you need; this Actor covers only official California State Bar attorney profiles.

### FAQ

#### Does this scrape every California attorney automatically?

No. It processes the names, bar numbers, and official profile URLs you supply, subject to `maxItems`.

#### Can I search by city or practice area?

Not in this release. The supported discovery input is the official quick-search name field; practice areas are extracted from matched profiles.

#### Does `hasDiscipline: false` prove there has never been discipline?

No. It means the currently retrieved public profile did not expose a discipline entry or linked case/document under the Actor's parser. Review the official profile for consequential decisions.

#### Can I schedule recurring checks?

Yes. Save input as an Apify Task and schedule it. Comparison, notification, and historical retention belong in your downstream workflow.

#### Are duplicate attorneys charged twice?

No. Profiles are deduplicated by canonical official URL before detail extraction and charging.

#### Does the Actor need an account or proxy?

No. It uses the current public server-rendered California State Bar pages directly.

# Actor input Schema

## `names` (type: `array`):

Full or partial attorney names to search in the official California State Bar directory.

## `barNumbers` (type: `array`):

California attorney bar numbers to verify. Numbers can be entered with or without leading zeroes.

## `profileUrls` (type: `array`):

Optional direct apps.calbar.ca.gov attorney profile URLs.

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

Stop after saving this many unique attorney profiles across all lookups.

## Actor input object example

```json
{
  "names": [
    "Koichiro Sato"
  ],
  "barNumbers": [],
  "profileUrls": [],
  "maxItems": 20
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset of normalized official attorney profiles, contacts, status, admission, and discipline history.

# 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 = {
    "names": [
        "Koichiro Sato"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/california-state-bar-attorney-lookup").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 = {
    "names": ["Koichiro Sato"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/california-state-bar-attorney-lookup").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "names": [
    "Koichiro Sato"
  ],
  "maxItems": 20
}' |
apify call automation-lab/california-state-bar-attorney-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/california-state-bar-attorney-lookup"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/izu8P3WdbznDfuHdy/builds/xCuiUDr86FRhglWRI/openapi.json
