# Martindale Lawyer Directory API (`johnvc/lawyer-directory-api`) Actor

US attorney profiles and law firm data as clean, structured JSON. Search by practice area, location, firm, or name, and get bar admissions, law school, admission year, firm, contact details, languages, and peer review ratings. Pay per profile, MCP-ready for Claude and AI agents.

- **URL**: https://apify.com/johnvc/lawyer-directory-api.md
- **Developed by:** [John](https://apify.com/johnvc) (community)
- **Categories:** AI
- **Stats:** 4 total users, 4 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.00 / 1,000 profile returneds

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/platform/actors/running/actors-in-store#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

## Martindale Lawyer Directory API | Law Firm Data and Attorney Profiles

US attorney profiles and law firm data as clean, structured JSON. Search the public [Martindale](https://www.martindale.com/) lawyer directory by practice area, location, firm, or name, and get back bar admissions with their years, law school, practice areas, firm and role, contact details, languages, and peer review ratings.

Search needs no URL: type "personal injury Houston" or "Austin, TX" and get structured profiles back. The credentials layer is what sets this data apart, since profiles carry the admission history, so you can tell a 2021 admittee from a 30-year veteran at a glance.

This is an independent tool. It is not affiliated with, endorsed by, or connected to Martindale, and it is not an official bar association directory. Admissions and ratings are reproduced as the directory publishes them. A peer review rating is that directory's own rating, not a legal credential and not a statement of license status; check the relevant state bar if you need to verify that someone is currently licensed.

### What this actor returns

- **Credentials:** every bar admission with its year and jurisdiction, first admission year, law school with degree and year, undergraduate education
- **Practice:** practice areas, practice area count, firm and role, firm founding year where listed
- **Contact:** office address, mailing address, all listed phone numbers, website
- **Reputation:** peer review stars and count, as published by the directory rather than by any bar. Zeros are kept deliberately: they mean no reviews yet, which is itself information
- **Person:** biography, languages spoken, memberships, awards, photo, video consultation platforms
- **Identity:** ISLN, the International Standard Lawyer Number, a stable identifier that survives firm moves

Every profile row also carries a one-line plain-language `summary`.

### A note on how search matches

The source's keyword search matches across names, schools, and locations together, and it is fuzzy. A search for "personal injury Houston" returns Houston personal-injury lawyers, and can also return an attorney whose surname is Houston. This is how the source works, not something this Actor can tighten. Every row carries the `searchKeyword` it matched, and the structured `state`, `address`, and `areasOfPractice` fields make the results straightforward to filter after collection.

### Use cases for law firm data and legal professional search

- **Build a practice-area directory for a region.** One keyword per city, filter on `areasOfPractice` and `state`, and export.
- **Screen counsel by experience.** `firstAdmissionYear` and the full admissions string separate the newly admitted from the veterans.
- **Map who practices in a jurisdiction.** Admissions carry both years and courts, including federal district admissions.
- **Enrich a legal-industry dataset.** ISLN gives you a stable join key per attorney.
- **Find multilingual representation.** The languages field is commonly populated.
- **Run a repeatable legal professional search.** Save one keyword set as a task, re-run it monthly, and diff the `firm` field to see who moved.

This Actor collects factual directory data. It is research tooling, not a marketing list product, and profiles describe professionals in their professional capacity.

### Input parameters

| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| `mode` | string | **Required** | `search` | `search` finds profiles from keywords. `url` collects specific profile pages. | `search` |
| `keywords` | array of strings | Required in search mode | (none) | Free-text searches: practice area plus city, a location, a firm, or a name. Up to 20 per run. | `["personal injury Houston"]` |
| `maxResultsPerKeyword` | integer | Optional | `25` | Profiles per keyword, from 1 to 2000. This is your cost control. | `25` |
| `profileUrls` | array of strings | Required in URL mode | (none) | Specific profile URLs of the form `martindale.com/attorney/<name>-<id>/`. Up to 500 per run. | `["https://www.martindale.com/attorney/demetris-guzman-301205226/"]` |

```json
{
  "mode": "search",
  "keywords": ["personal injury Houston", "Austin, TX"],
  "maxResultsPerKeyword": 25
}
```

### Example output

One dataset row per attorney profile. Every row carries `result_type`, the `searchKeyword` that matched it in search mode, the identity and credential fields listed above, and a `fetched_at` UTC timestamp. Two saved dataset views ship with the Actor: **Attorneys overview** (name, practice areas, state, address, admission year, firm, phones) and **Credentials** (law school, full admissions, languages, peer review).

```json
{
  "result_type": "lawyer",
  "searchKeyword": "personal injury Houston",
  "isln": "1001166868",
  "name": "Demetris Guzman",
  "areasOfPractice": ["Business and Commercial", "Civil Rights", "Personal Injury"],
  "practiceCount": 3,
  "state": "TX",
  "address": "7151 Office City Drive, Houston, TX 77087",
  "phones": ["346-327-1690", "832-530-4070"],
  "firm": "Trial Attorney at The Gonzalez Law Group, PLLC",
  "lawSchool": "South Texas College of Law Houston, J.D., 2020",
  "university": "The University of Texas at San Antonio, B.A., Political Science",
  "firstAdmissionYear": 2021,
  "admissions": "2021, Texas; 2021, United States District Court for the Southern District of Texas",
  "languages": "English and Spanish",
  "peerReview": { "stars": 0, "reviewCount": 0 },
  "website": "https://www.gonzalezlawgroup.net/",
  "profileUrl": "https://www.martindale.com/attorney/demetris-guzman-301205226/",
  "summary": "Demetris Guzman, practicing Business and Commercial, Civil Rights, Personal Injury, at 7151 Office City Drive, Houston, TX 77087. Admitted 2021.",
  "fetched_at": "2026-08-05T18:55:01.539Z"
}
```

A keyword or URL that returns nothing produces a row with `result_type: "error"` and a plain-language `error_message`.

### Pricing

Pay per result. One event, `lawyer-scraped`, is charged once for every profile pushed to the dataset. Nothing is charged for a keyword that matches nothing.

`maxResultsPerKeyword` caps what a run can cost, and the cap is applied at the source. Current rates are shown on the Store card.

### Speed

A keyword search takes a few minutes, because the source walks result pages and hydrates each profile. The Actor collects in chunks and pushes each chunk as it completes.

### How to get started

1. [View on Apify Store](https://apify.com/johnvc/lawyer-directory-api?fpr=9n7kx3) and click Try for free.
2. Leave **Mode** on `search` and enter a keyword such as a practice area plus a city.
3. Run it. Results appear on the Output tab and export as JSON, CSV, or Excel. The **Credentials** view puts law school, admissions, and peer review side by side.

Prefer code? The [example repo with a Python quick start and MCP install walkthroughs](https://github.com/johnisanerd/Apify-Martindale-Lawyer-Directory-API) shows a working client and the setup steps for Claude, Cursor, and ChatGPT.

### 🔌 Use this API from Claude (MCP)

Add this Actor as a tool in [Claude Code](https://claude.ai/referral/uIlpa7nPLg) (free trial), [Claude Cowork](https://claude.ai/referral/uIlpa7nPLg) (free trial), Cursor, or any other MCP client through the hosted Apify MCP server:

```
https://mcp.apify.com/?tools=actors,docs,johnvc/lawyer-directory-api
```

With [Claude Code](https://claude.ai/referral/uIlpa7nPLg) (free trial):

```
claude mcp add --transport http lawyers "https://mcp.apify.com/?tools=actors,docs,johnvc/lawyer-directory-api"
```

Then ask your agent something like "find family law attorneys in Austin admitted before 2010".

https://www.youtube.com/watch?v=jREWahDGhJM

Apify MCP integration docs: https://docs.apify.com/platform/integrations/mcp

### 💸 Pay per run with crypto (x402)

The Martindale Lawyer Directory API supports agentic payments via the [x402 protocol](https://docs.apify.com/platform/integrations/x402).
AI agents and MCP clients can pay for runs in USDC (on Base) with no Apify account or API token needed:
point your agent at the [Apify MCP server](https://mcp.apify.com/?tools=actors,docs,johnvc/lawyer-directory-api) and it can
discover, pay for, and run this Actor autonomously. Read the
[Apify x402 announcement](https://apify.com/change-log/pay-for-apify-actors-with-x402?fpr=9n7kx3) for details.

### 🔌 Integrations: Automate Attorney and Law Firm Data Collection

One run answers one question. Directory data earns its keep when you run it more than once, because the [Martindale](https://www.martindale.com/) listings themselves move: attorneys change firms, new admittees appear, and phone numbers go stale. With the native [Apify platform integrations](https://docs.apify.com/platform/integrations) you can wire this Actor into your stack without running a server or a cron job of your own.

#### Tasks and schedules: keep a roster current

The pattern is one saved task per thing you track, one schedule across all of them.

1. **Create a task.** A [saved task](https://docs.apify.com/platform/actors/running/tasks) is this Actor plus a saved input. Give each slice its own name, for example *"TX personal injury"* with `mode: "search"`, `keywords: ["personal injury Houston", "personal injury Dallas"]`, and `maxResultsPerKeyword: 50`. Click **Create empty task** on the Actor page, fill in the input, and save.
2. **Attach a schedule.** Open [Schedules](https://docs.apify.com/platform/schedules) in the Apify Console, create a schedule with a standard cron expression, and add your tasks to it. Useful examples: `0 7 * * *` for every morning at 7 AM, `0 */6 * * *` for every six hours, `0 9 * * 1` for Mondays at 9 AM. One schedule can trigger many tasks, so a single "monthly roster refresh" schedule can cover every practice area and city you saved.
3. **Diff the results.** Each run appends to the task's dataset. Join runs on `isln`, the identifier that survives a firm move, and compare `firm`, `address`, and `admissions` to see what changed.

The task [Track Attorney Firm Moves with a Profile Watchlist](https://apify.com/johnvc/lawyer-directory-api/examples/track-attorney-firm-moves-with-a-profile-watchlist?fpr=9n7kx3) is that recipe already wired up.

#### n8n

There is no dedicated community node for this Actor yet, so use the general [Apify n8n integration](https://docs.apify.com/platform/integrations/n8n), which can run any Actor and read its dataset. A workflow that works well: **Schedule Trigger** monthly, then **Apify: Run Actor** with your keywords, then a **Filter** on `firstAdmissionYear` or `state`, then a **Slack** or **email** node with the new names.

#### Make and Zapier

Both have native Apify integrations, [Apify on Make](https://docs.apify.com/platform/integrations/make) and [Apify on Zapier](https://docs.apify.com/platform/integrations/zapier), with "Run Actor" and "Get Dataset Items" actions. The same pattern applies: trigger on a schedule, run this Actor, filter the rows, then notify or store them.

#### Supabase: keep attorney history in your own database

Directory data becomes far more useful once you have two snapshots of it. [Supabase](https://supabase.com/) (hosted Postgres) is an easy destination, and there are two paths:

- **No code:** in n8n, connect the Apify node to the built-in Supabase node and insert one row per profile after each scheduled run.
- **A few lines of Python:** run the Actor and upsert the profile rows on `isln`.

```python
from apify_client import ApifyClient
from supabase import create_client

apify = ApifyClient("YOUR_APIFY_TOKEN")
supabase = create_client("https://YOUR_PROJECT.supabase.co", "YOUR_SERVICE_ROLE_KEY")

run = apify.actor("johnvc/lawyer-directory-api").call(
    run_input={
        "mode": "search",
        "keywords": ["personal injury Houston", "family law Austin, TX"],
        "maxResultsPerKeyword": 25,
    }
)

rows = [
    {
        "isln": item["isln"],
        "name": item.get("name"),
        "firm": item.get("firm"),
        "state": item.get("state"),
        "areas_of_practice": item.get("areasOfPractice"),
        "law_school": item.get("lawSchool"),
        "first_admission_year": item.get("firstAdmissionYear"),
        "admissions": item.get("admissions"),
        "languages": item.get("languages"),
        "profile_url": item.get("profileUrl"),
        "fetched_at": item.get("fetched_at"),
    }
    for item in apify.dataset(run.default_dataset_id).iterate_items()
    if item.get("result_type") == "lawyer"
]

if rows:
    supabase.table("attorney_profiles").upsert(rows, on_conflict="isln").execute()
```

Run that on a schedule and you accumulate a history of who practices where, which is the part a single scrape cannot give you.

#### MCP and AI agents

Apify exposes this Actor through the [Apify MCP server](https://mcp.apify.com/), so MCP-compatible assistants such as Claude and Cursor can run a live lookup as a tool and answer questions like "which immigration attorneys in Miami list Portuguese?" with real rows rather than recall. The task [Look Up US Attorneys in Claude via MCP](https://apify.com/johnvc/lawyer-directory-api/examples/look-up-us-attorneys-in-claude-via-mcp?fpr=9n7kx3) walks through the setup.

#### Webhooks

For anything custom, attach an [Apify webhook](https://docs.apify.com/platform/integrations/webhooks) to the `ACTOR.RUN.SUCCEEDED` event. When a scheduled run finishes, Apify POSTs the run details, including the dataset ID, to your endpoint, which can then pull the rows and update a sheet, a dashboard, or a CRM record.

### 🔗 Related Tools

- [Google Scholar Case Law API](https://apify.com/johnvc/google-scholar-case-law?fpr=9n7kx3) for the case law these attorneys practice against
- [LinkedIn Profile API](https://apify.com/johnvc/linkedin-profile-api?fpr=9n7kx3) for a professional-network view of the same person
- [LinkedIn Company API](https://apify.com/johnvc/linkedin-company-api?fpr=9n7kx3) for firmographics on the law firm itself, headcount, industry, and locations
- [Owler Company Intelligence API](https://apify.com/johnvc/owler-company-api?fpr=9n7kx3) for the companies a firm's clients come from
- [Investment Finance Professionals](https://apify.com/johnvc/SECInvestmentAdvisorContacts?fpr=9n7kx3) for the same licensed-professional lookup on the finance side

Older alternatives such as [Martindale Scraper](https://apify.com/jungle_synthesizer/martindale-scraper?fpr=9n7kx3) read the same directory, but its Store page currently shows a 79 percent run success rate and a single one-star review. This API is actively maintained, charges only for profiles actually delivered, and returns a labelled error row instead of silence when a keyword matches nothing.

### Applications

Ready-to-run examples of this API in action. Open any one and run it in a single click.

#### Attorney Data API: Bar Admissions and Law School

Pull the credentials layer on its own: law school, degree year, and every admission with its jurisdiction.
[Run this task](https://apify.com/johnvc/lawyer-directory-api/examples/attorney-data-api-bar-admissions-and-law-school?fpr=9n7kx3)

#### Find Attorneys by Practice Area in a US City

Practice area search in one keyword, filtered afterwards on `areasOfPractice` and `state`.
[Run this task](https://apify.com/johnvc/lawyer-directory-api/examples/find-attorneys-by-practice-area-in-a-us-city?fpr=9n7kx3)

#### Track Attorney Firm Moves with a Profile Watchlist

Re-run a saved profile list on a schedule and diff the `firm` field to catch lateral moves.
[Run this task](https://apify.com/johnvc/lawyer-directory-api/examples/track-attorney-firm-moves-with-a-profile-watchlist?fpr=9n7kx3)

#### Look Up US Attorneys in Claude via MCP

Add the Actor to an MCP client and ask for attorneys in plain language mid-conversation.
[Run this task](https://apify.com/johnvc/lawyer-directory-api/examples/look-up-us-attorneys-in-claude-via-mcp?fpr=9n7kx3)

#### Export a List of Lawyers in a City to CSV

One city, one export, ready for a spreadsheet or a database load.
[Run this task](https://apify.com/johnvc/lawyer-directory-api/examples/export-a-list-of-lawyers-in-a-city-to-csv?fpr=9n7kx3)

#### Check Federal Court Admissions for a List of Attorneys

The `admissions` string carries district and circuit admissions, so you can screen for federal practice.
[Run this task](https://apify.com/johnvc/lawyer-directory-api/examples/check-federal-court-admissions-for-attorneys?fpr=9n7kx3)

#### 查询美国律师的执业资格与执业年份 (Check US Attorney Credentials and Admission Year)

Collect bar admissions, law school, and first admission year for US attorneys, in Simplified Chinese.
[Run this task](https://apify.com/johnvc/lawyer-directory-api/examples/chaxun-meiguo-lvshi-zhiye-zige?fpr=9n7kx3)

#### 为出海企业检索美国律所与联系方式 (Find US Law Firms and Contact Details)

Build a shortlist of US firms and their contact details for a company expanding into the United States.
[Run this task](https://apify.com/johnvc/lawyer-directory-api/examples/jiansuo-meiguo-lvsuo-yu-lianxi-fangshi?fpr=9n7kx3)

### ❓ FAQ

#### How do I get law firm data by practice area?

Search a practice area, optionally with a city, then group the results by the `firm` field. Each profile carries its firm and role, so a set of profiles doubles as a firm list.

#### How do I find attorneys in a specific city?

Include the city in the keyword, then filter the rows on `state` and `address`. The keyword match is fuzzy across names and locations, so the structured fields are the reliable filter.

#### How do I build a list of attorneys by state?

Run one keyword per major city in the state rather than one keyword for the state itself, since the directory ranks city queries better, then deduplicate on `isln` and keep the rows whose `state` matches. Save that keyword set as a task so the same list can be rebuilt on a schedule.

#### How do law firms get clean data for legal reporting?

They start from a structured source rather than a copy and paste. Every row here arrives typed: `firstAdmissionYear` as an integer, `areasOfPractice` as an array, `admissions` as a single parseable string per attorney. That is enough to produce counts by practice area, by admission cohort, or by jurisdiction without any manual cleanup, and the two saved dataset views export straight to CSV or Excel.

#### How do I find lawyers who speak a specific language?

The `languages` field is populated on most profiles and reads the way the directory phrases it, for example "English and Spanish". Collect a city or a practice area, then filter the rows on that field. It is free text rather than a code list, so match loosely: "Spanish" catches "English and Spanish" too.

#### Can I tell how experienced an attorney is?

Yes. `firstAdmissionYear` is a clean integer, and `admissions` lists every jurisdiction with its year, including federal courts.

#### What is an ISLN?

The International Standard Lawyer Number, a stable identifier for an individual attorney. It survives firm moves and name changes, which makes it the right join key for enrichment.

#### Why do some profiles show zero peer reviews?

Because they have none yet, which is worth knowing. Zeros are kept rather than dropped, so absence of reviews is distinguishable from missing data.

#### Does it return client reviews?

No. Client-review fields were empty on every profile tested, so they are deliberately not part of the output rather than being present and always blank.

#### Can I search by law school?

Yes, the keyword matches school names too, so "Harvard" returns alumni. Note it may also match attorneys named Harvard, so filter on `lawSchool` afterwards.

#### Is this an official Martindale API or a bar association directory?

No on both counts. This is an independent tool and it is not affiliated with, endorsed by, or connected to [Martindale](https://www.martindale.com/). It is also not a state bar lookup: a peer review rating is the directory's own rating, not a legal credential, and nothing here confirms that an attorney is currently licensed or in good standing. For licensure and discipline, go to the relevant [bar association](https://en.wikipedia.org/wiki/Bar_association) or state bar's own lookup.

#### Is this suitable for solicitation lists?

It is built for research, licensing verification, market mapping, and enrichment. If you plan outreach, you are responsible for compliance with the bar and solicitation rules that apply to you.

#### Is it legal to scrape a public lawyer directory?

Collecting publicly published professional listings is generally treated as lawful, and this Actor reads only pages that are public and returns them as structured data. What you then do with the data is a separate question governed by your own obligations, including the advertising and solicitation rules of the bars you practice under, plus any applicable data protection law. Apify's write-up on [the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) is a good starting point.

#### Can I schedule this attorney directory Scraper to run automatically?

Yes, and this is where the data gets interesting. Save your input as a [task](https://docs.apify.com/platform/actors/running/tasks), then attach a [schedule](https://docs.apify.com/platform/schedules) from the Actor's **Actions**, then **Schedule** menu. Standard cron expressions apply: `0 7 * * *` runs every morning at 7 AM, `0 */6 * * *` every six hours, `0 9 * * 1` on Mondays. One schedule can trigger many tasks at once, so a single monthly job can refresh every city and practice area you track. Each run appends to the task's dataset, so joining runs on `isln` gives you a history of firm moves and new admissions. The Integrations section above has the full recipe, including a Supabase upsert.

#### Should I use an API or a Web Scraper for legal professional search?

An official directory [API](https://en.wikipedia.org/wiki/API) is rate limited, quota bound, usually behind a commercial agreement, and often omits the credential fields you actually want. A no-code [web scraper](https://en.wikipedia.org/wiki/Web_scraping) gets you the page but leaves you parsing HTML. This Actor sits in between: it behaves like a clean API endpoint you call yourself, with no quota, and it returns parsed, typed fields instead of markup. Call it from the Console, from code, or from an agent.

#### Can I integrate this lawyer directory Scraper with other apps?

Yes. Through [Apify integrations](https://docs.apify.com/platform/integrations) the Actor connects to most cloud services, including [Make](https://docs.apify.com/platform/integrations/make), [Zapier](https://docs.apify.com/platform/integrations/zapier), [Slack](https://docs.apify.com/platform/integrations/slack), [Google Drive](https://docs.apify.com/platform/integrations/drive), and [n8n](https://docs.apify.com/platform/integrations/n8n). For anything custom, a [webhook](https://docs.apify.com/platform/integrations/webhooks) on `ACTOR.RUN.SUCCEEDED` hands your endpoint the dataset ID the moment a run finishes. The Integrations section above has full recipes.

#### Can I run the Martindale Lawyer Directory API with the Apify API?

Yes. The Apify API runs the Actor, schedules it, and fetches its datasets programmatically, and the `apify-client` package exists for both Python and Node.js. The Actor's own endpoints, with ready-made snippets, are on its [API tab](https://apify.com/johnvc/lawyer-directory-api/api?fpr=9n7kx3).

#### Can I use this API through an MCP Server?

Yes. Add it as a tool in any MCP client through the hosted [Apify MCP server](https://mcp.apify.com/) using the Actor-specific URL `https://mcp.apify.com/?tools=actors,docs,johnvc/lawyer-directory-api`. That works with [Claude Code](https://claude.ai/referral/uIlpa7nPLg) (free trial), [Claude Cowork](https://claude.ai/referral/uIlpa7nPLg) (free trial), Cursor, and other MCP-compatible assistants. See the [Apify MCP docs](https://docs.apify.com/platform/integrations/mcp) for the setup, and the MCP section above for the one-line install command.

#### How much does it cost to scrape attorney profiles?

You pay per profile returned, once per row pushed to the dataset, at the rate shown on the Store card. A keyword that matches nothing is free. `maxResultsPerKeyword` is the cap, so 10 keywords at 25 profiles each is a run of at most 250 billable rows.

#### How else can I collect legal and professional profile data?

Pair this with the [Google Scholar Case Law API](https://apify.com/johnvc/google-scholar-case-law?fpr=9n7kx3) to read the opinions in the practice areas you just mapped, the [LinkedIn Profile API](https://apify.com/johnvc/linkedin-profile-api?fpr=9n7kx3) for a professional-network view of the same attorney, and the [LinkedIn Company API](https://apify.com/johnvc/linkedin-company-api?fpr=9n7kx3) for firmographics on the firm behind the name. The Related Tools section above lists the rest.

### 🌐 About Alpha OSINT

This Actor is part of [Alpha OSINT](https://www.alphaosint.com), toolset of financial and operations data sources and APIs.
For support or requests for this actor, please start a ticket [directly on our support page](https://apify.com/johnvc/lawyer-directory-api/issues/open?fpr=9n7kx3).

Last Updated: 2026.08.10

# Actor input Schema

## `mode` (type: `string`):

Search finds attorney profiles from free-text keywords and needs no URL. URL collects specific profile pages you already hold.

## `keywords` (type: `array`):

Free-text searches: a practice area with a city ("personal injury Houston"), a location ("Austin, TX"), a firm, or an attorney name. Note the source matches across names, schools, and locations together, so a place word can also match a person named after it; the searchKeyword field on each row lets you filter afterwards. Up to 20 per run.

## `maxResultsPerKeyword` (type: `integer`):

How many profiles to return for each keyword. You are charged per profile returned, so this is also your cost control.

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

Specific attorney profile URLs, used in URL mode. Up to 500 per run.

## Actor input object example

```json
{
  "mode": "search",
  "keywords": [
    "personal injury Houston"
  ],
  "maxResultsPerKeyword": 25
}
```

# Actor output Schema

## `allResults` (type: `string`):

Every dataset item from this run: collected profiles and any error rows.

## `overview` (type: `string`):

Tabular overview: name, practice areas, state, address, admission year, firm, phones.

## `credentials` (type: `string`):

Law school, full bar admissions, languages, and peer review per attorney.

# 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 = {
    "keywords": [
        "personal injury Houston"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("johnvc/lawyer-directory-api").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 = { "keywords": ["personal injury Houston"] }

# Run the Actor and wait for it to finish
run = client.actor("johnvc/lawyer-directory-api").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 '{
  "keywords": [
    "personal injury Houston"
  ]
}' |
apify call johnvc/lawyer-directory-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,johnvc/lawyer-directory-api"
        }
    }
}

```

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/mYvnxgsWO1phJxnWW/builds/PoGcZfoe2arNQJK0p/openapi.json
