Justia Lawyer Directory Scraper — Attorney Leads & Phones avatar

Justia Lawyer Directory Scraper — Attorney Leads & Phones

Pricing

$3.00 / 1,000 per attorney returneds

Go to Apify Store
Justia Lawyer Directory Scraper — Attorney Leads & Phones

Justia Lawyer Directory Scraper — Attorney Leads & Phones

One row per attorney from the Justia lawyer directory: firm, practice areas with sub-areas, every listed phone, website, office address with lat/lon, admission year, law school, badges and client rating. Pick state, city and practice area from dropdowns, or paste profile URLs. No login, no API key.

Pricing

$3.00 / 1,000 per attorney returneds

Rating

0.0

(0)

Developer

Scrapers Delight

Scrapers Delight

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

One row per attorney from the Justia lawyer directory, carrying fullName, firmName, practiceAreas with sub-areas, phone (every listed number), website, contactFormUrl, street / city / state / zip, latitude / longitude, yearAdmitted, yearsLicensed, lawSchool and degree, badges, listingTier, client rating, languages, fee terms, bar associations, awards and the attorney's Avvo / Martindale / Lawyers.com profile links.

Filter by state, city and practice area — all picked from dropdowns, no slugs to type — or paste attorney profile URLs and scrape exactly those.

Every row is a claimed, self-maintained profile. Measured, not assumed: 360 of 360 rows across two independent samples carried the "Claimed Lawyer Profile" badge, with phone fill at 99.5–100%. An unclaimed directory stub is a name and a city. A claimed profile is the firm, the phone, the website, the practice-area tree and the credentials below.

No login. No API key. No CAPTCHA-solving service. Justia publishes no email address for any attorney, and none is invented here — see the FAQ for what you get instead.

🚀 Quick start

The Actor ships prefilled with a working demo — Texas → Austin → 100 attorneys. Press Start and you get rows without typing anything. Measured on the Apify platform with exactly that input, 2026-08-13: 100 attorneys in 2 min 8 s — 20 listing pages plus 102 profile pages, 0 failed requests, 1 challenge-token mint, 0 rate-limit pauses, and 100 rows billed at $0.30.

{
"states": ["texas"], // picked from a dropdown of the directory's own 52 state slugs
"cities": ["austin"], // leave empty to crawl the whole state
"maxItems": 100 // 100 × $0.003 = $0.30, your hard cost ceiling
}

Three more inputs worth copying:

// A whole practice area, statewide — the classic lead pull
{ "states": ["florida"], "practiceAreas": ["personal-injury"], "maxItems": 2000 }
// Several metros at once. Pair each city with its state, or every city is tried in every state
{ "states": ["texas", "new-york"], "cities": ["texas/houston", "new-york/new-york"],
"practiceAreas": ["estate-planning"], "withWebsiteOnly": true, "maxItems": 1000 }
// Refresh a known list of attorneys — no listing crawl, one fetch per URL
{ "profileUrls": ["https://lawyers.justia.com/lawyer/richard-m-ursha-207812"],
"includeBiography": true }

✨ Why use this scraper

  • Claimed profiles only, measured at 360/360. The rows come from the side of the directory attorneys maintain themselves, which is why the contact fields are actually filled in.
  • The practice-area tree, not a tag list. Each row carries practiceAreaDetail — the area plus its sub-areas ("Criminal Law → Drug Crimes, Expungement, Fraud, Gun Crimes, Theft, Violent Crimes"). Attorneys average 2.9 areas in a metro crawl and 3.7 in a whole-state crawl.
  • You can see who already buys legal marketing. listingTier and badges expose the paid placement level (PREMIUM / LII Platinum / Gold / Silver / Claimed). The metro sample was 203 of 220 Premium; the whole-state sample 55 of 140. If you sell to law firms, that flag is the qualified/unqualified split.
  • Cross-directory identity for free. otherDirectoryProfiles returns the same attorney's Avvo, Martindale, Lawyers.com and Super Lawyers URLs — 74.1% of metro rows, 35.7% of whole-state rows — so you can join this dataset to those directories without a fuzzy match.
  • Every phone number, not just the first. phones is the full list, deduplicated on digits so the same number formatted two ways does not look like two numbers. phone is the primary.
  • Geocoded offices. latitude/longitude at 100% in both samples, plus offices[] for attorneys who list more than one address.
  • It handles the site's edge challenge itself. One headless page load lets the site's own challenge script issue a token, then the crawl runs on plain HTTP with it. Measured on the last full validation run: 235 of 235 requests clean, 0 failures. Runs direct, with no proxy.
  • Client rating is on a 0–10 scale, and ratingScale says so on every row — no silent five-star/ten-point mixups when you load it into a warehouse.

🎯 Use cases

You are a…Use it to…
Legal-SaaS / practice-management sales (Clio, MyCase, Filevine, Smokeball, Lawmatics)Segment by practiceAreas + firm, call the phone, enrich the website domain
Legal marketing / SEO agencyTarget the attorneys already paying for placement — filter your export on listingTier = PREMIUM and the LII badges
Malpractice & professional-liability brokerCut by jurisdictions, yearAdmitted and practice mix; minYearsLicensed does the tenure filter in-run
Legal recruiterFilter on lawSchool, lawSchoolGraduationYear, yearsOfExperience and sub-areas after export
Expert-witness / co-counsel deskFind niche sub-areas, languages and multi-jurisdiction admissions in a named metro
Legal-data / directory productJoin to Avvo, Martindale, Lawyers.com and Super Lawyers on otherDirectoryProfiles instead of name-matching

📥 Supported inputs

InputExampleWhat it does
Statetexas (picked from a dropdown)Crawls that whole state's listing
State + citytexas + austin, or texas/austinCrawls the city listing (attorneys serving that city)
State (+ city) + practice areaflorida + personal-injuryOne listing per state × city × area
Attorney profile URLhttps://lawyers.justia.com/lawyer/jane-doe-123456Scrapes that attorney directly, no listing crawl. The LII host URL works too

Not supported: email addresses (the directory publishes none — see the FAQ), law-firm /organization/… pages, case law, dockets, client reviews as individual rows, and anything behind a login. A practice area on its own is also not a valid scope: the directory only lists attorneys under a state, or a state plus a city.

Read this before you buy rows

  1. A city listing returns attorneys serving that city, drawn from the surrounding region — not only attorneys with an office in it. A crawl of texas/austin legitimately returns Houston and San Antonio firms. Each row's own city/state is the attorney's actual office, so filter on that if you need strict geography.
  2. Fill depends on the market you crawl, and the gap is large. Big-metro listings are dominated by attorneys paying for Premium placement, who fill their profiles in completely; a whole-state crawl reaches ordinary claimed profiles. Both samples are published below — plan against the one that matches your scope, not against the better-looking one.
  3. rating is out of 10, not out of 5, and only a minority of profiles have one: 30.9% in the metro sample, 4.3% in the whole-state sample. ratingScale is on every row. This is not a ratings product.
  4. yearAdmitted is the earliest admission year printed on the profile, across all listed jurisdictions including federal courts, so an attorney who lists only a federal admission under-states their tenure. Roughly 1 in 4 profiles print the bar organisation ("State Bar of Montana") in that slot instead of a year; those come back in jurisdictions[].barOrganization with yearAdmitted: null rather than a guess.
  5. The listing repeats itself; the dataset does not. Every listing page reprints its sponsored block. Deduplication happens on the numeric profile id before any profile is fetched, so duplicates never reach the dataset and never reach your bill.

📦 Output sample

One real row, from a real run:

{
"profileId": "207812",
"fullName": "Richard M. Ursha",
"firmName": "Richard Ursha, Attorney at Law PLLC",
"jobTitle": "Attorney",
"yearsOfExperience": 24,
"yearAdmitted": 2002,
"yearsLicensed": 24,
"practiceAreas": ["Criminal Law", "DUI & DWI", "Domestic Violence", "Juvenile Law", "White Collar Crime"],
"practiceAreaDetail": [
{ "area": "Criminal Law", "subAreas": ["Drug Crimes", "Expungement", "Fraud", "Gun Crimes", "Theft", "Violent Crimes"] }
],
"phone": "(512) 847-1717",
"phones": ["(512) 847-1717", "(512) 512-1179", "(512) 738-1266"],
"website": "http://www.hillcountrylawyers.com/Attorney-Profile.aspx",
"contactFormUrl": "https://lawyers.law.cornell.edu/lawyer/richard-m-ursha-207812/contact",
"street": "2401 Hunter Road, Ste. 200",
"city": "San Marcos", "state": "TX", "zip": "78666", "country": "US",
"latitude": 29.8594032, "longitude": -97.9665581,
"lawSchool": "South Texas College of Law Houston",
"lawSchoolDegree": "J.D.", "lawSchoolGraduationYear": 2002,
"jurisdictions": [{ "jurisdiction": "Texas", "admittedYear": 2002, "barOrganization": null }],
"badges": ["Claimed Lawyer Profile", "LII Platinum", "Social Media"],
"isClaimed": true, "listingTier": "PREMIUM",
"rating": 10, "ratingScale": 10, "reviewCount": 2,
"languages": ["English"],
"fees": ["Free Consultation", "Credit Cards Accepted"],
"freeConsultation": true, "creditCardsAccepted": true,
"associations": [{ "organization": "Texas State Bar # 24037624", "role": "Member" }],
"socialProfiles": { "facebook": "…", "linkedin": "…", "twitter": "…" },
"otherDirectoryProfiles": ["https://www.avvo.com/…", "https://www.martindale.com/…"],
"justiaProfileUrl": "https://lawyers.justia.com/lawyer/richard-m-ursha-207812"
}

Three fields people misread:

  • rating: 10 is ten out of ten, not a percentage and not a 0–5 star score. ratingScale carries the denominator.
  • reviewCount: 0 means Justia published a rating block with no reviews; null means it published no rating block at all. They are different states and are not merged.
  • yearsOfExperience is self-reported by the attorney; yearsLicensed is computed from the earliest admission year on the profile. They disagree for some attorneys, and both are shipped.

🗂 Key output fields

FieldTypeNotes
profileId / fullNamestringThe numeric id is the dedupe key and the stable join key
firmName / jobTitlestringFirm from the profile's structured data
practiceAreas / practiceAreaDetailarrayFlat list, and the area → sub-area tree. Both of the directory blocks are read — the main one and "Additional Practice Areas" — so nothing the attorney listed is dropped
phone / phones / faxstring / arrayPrimary number, then every number listed
website / websitesstring / arrayFirm site and blog
contactFormUrlstringOn every row — the directory's own contact channel for that attorney
street / city / state / zip / countrystringOffice address; ALL-CAPS city names are title-cased, two-letter states upper-cased
latitude / longitudenumber100% fill in both samples
officeCount / offices[]number / arrayEvery office when the attorney lists more than one
yearAdmitted / yearsLicensed / yearsOfExperiencenumberComputed, computed, self-reported
jurisdictions[]arrayjurisdiction, admittedYear, barOrganization
lawSchool / lawSchoolDegree / lawSchoolGraduationYear / education[]string / arrayDegree parsed out of "J.D. (2012) | Degree of Law"
badges / isClaimed / listingTierarray / bool / stringPaid-placement and claimed-profile signals
rating / ratingScale / reviewCountnumberOnly with "Include rating and review count" (on by default)
languages / fees / freeConsultation / creditCardsAcceptedarray / boolSelf-reported service terms
associations[] / awards[] / certifications[] / experience[]arrayOnly with "Include credentials" (on by default)
biographystringOnly with "Include the biography text" (off by default)
socialProfiles / otherDirectoryProfilesobject / arrayLinkedIn, Facebook, X, YouTube, Instagram; Avvo / Martindale / Lawyers.com / Super Lawyers
photoUrl / profileUrl / justiaProfileUrl / scrapedAtstringProvenance. scrapedAt is ISO-8601 UTC

📊 Field fill — measured on 220 metro rows and 140 whole-state rows

Fill depends heavily on the market you crawl, so both samples are published. The metro sample was 203/220 Premium listings; the whole-state sample 55/140. Plan against the column that matches the scope you are going to run.

FieldMetro sample (220 rows)Whole-state sample (140 rows)
fullName, profileId, badges, isClaimed100%100%
firmName100%100%
latitude / longitude100%100%
phone99.5%100%
street / city / state / zip99.5%99.3%
website99.5%67.9%
lawSchool100%70.0%
associations95.9%84.3%
biography96.8%64.3%
languages96.4%37.1%
social profiles (any)92.7%49.3%
yearsOfExperience91.4%75.7%
yearAdmitted / yearsLicensed85.9%71.4%
practiceAreas99–100%100%
otherDirectoryProfiles74.1%35.7%
awards73.2%17.1%
freeConsultation66.4%33.6%
lawSchoolGraduationYear86.0%88.6%
fax29.1%23.6%
rating / reviewCount30.9%4.3%
email0%0%

The headline that could mislead you: this is a phone-and-firm product, not a ratings product and not an email product. Every run prints its own measured fill in the log, on its own rows.

Re-measured 2026-08-19 (audit). practiceAreas used to read 77.7% / 79.3% because the parser matched only the plural block heading "Practice Areas", while the directory titles the block "Practice Area" for an attorney with exactly one — and published a second block, "Additional Practice Areas", that was never read at all. Both are now read and merged: 314 of 316 rows across five fresh runs (two Austin runs of 100 and three whole-state runs), and 114 of 114 across nine statewide listings. The two rows that still have none were pulled and read by hand: the directory publishes no practice-area block of any kind on them — the strings "practice area" and "practice areas" do not appear anywhere in the 134 KB page. lawSchoolGraduationYear moved the same way (the year is often published only as the entry's end date, not inside the degree line): 275 of 316. The other columns in the table are unchanged.

The three columns that are genuinely thin are the source's own gaps, verified against the raw profile HTML on 2026-08-19. Across the same 316 rows: rating / ratingScale / reviewCount 123 of 316 (38.9%), certifications 140 of 316 (44.3%), fax 96 of 316 (30.4%). Five profiles were pulled for each of the three and read directly: 0 of 5 empty-rating profiles contained an AggregateRating or a Review block anywhere on the page, 0 of 5 empty-fax profiles carried anything but "faxNumber": [] in their own structured data, and 0 of 5 empty-certifications profiles had a certifications block at all. Every profile that does publish one was extracted (checked the other way too: all 25 rows in the Austin run that list a fax anywhere in offices[] also carry the top-level fax). None of the three is a scrape failure, and none can be filled from anywhere else on the page. Note that rating, reviewCount, fax and certifications are featured columns in the dataset's table views, so those columns will look sparse in the preview — that is the directory, not a dropped field.

⚙️ Input parameters

FieldTypeDefaultWhat it does
statesmulti-select["texas"]52 options, the directory's own slugs — 50 states plus District of Columbia and Puerto Rico
citiesstring list["austin"]austin, or texas/austin to pin a city to its state when you list several. Empty = whole state
practiceAreasmulti-selectThe directory's 56 areas, picked by name. Each area is a separate listing
profileUrlsstring listScrape named attorneys and skip the listing crawl. Either host works
withPhoneOnlybooleantrueOn by default — there is no email here, so a row with no phone is not contactable. Costs ~0–0.5% of rows
withWebsiteOnlybooleanfalseFor enrichment workflows. Costs ~32% of a whole-state crawl, ~0.5% of a metro one
minYearsLicensedintegerFalls back to self-reported yearsOfExperience when the profile prints no admission year
includeCredentialsbooleantrueEducation, experience, awards, associations, certifications. No extra requests
includeReviewsMetabooleantrueRating (out of 10) and review count. No extra requests
includeBiographybooleanfalseThe full self-written bio — long, but it is the copy for personalised outreach
maxItemsinteger100Your hard cost ceiling. 100 = $0.30, 1,000 = $3.00
maxPagesPerListinginteger20~12–15 new attorneys per page after duplicates are removed
maxConcurrencyinteger2Will not speed the run up — the crawl is paced. 2 is measured-optimal
proxyConfigurationproxy(none)Leave empty. The Actor runs direct and clears the edge challenge itself

Pricing

$0.003 per attorney returned — $3 per 1,000. Charged on the attorney-scraped event. No monthly platform fee from this Actor.

RunAttorneysCost
The prefilled demo100$0.30
One practice area in one metro500$1.50
A statewide practice-area pull2,000$6.00
A multi-state campaign list10,000$30.00

What you are not charged for:

  • Duplicates. Profile ids are deduplicated before anything is fetched, so the dataset — and your bill — never holds the same attorney twice.
  • Rows your filters removed. withPhoneOnly, withWebsiteOnly and minYearsLicensed are applied after the profile page loads. A filtered-out attorney costs the Actor a fetch and costs you nothing.
  • Retries, challenge-token mints and rate-limit pauses. Those are the Actor's problem.

Rows are charged as they are pushed (Actor.pushData(items, 'attorney-scraped')), so if you hit a budget cap you get whole rows and stop, never a half-billed dataset. maxItems is the cost dial: maxItems × $0.003 is the most a run can cost you.

Honest limits

  • No email addresses. Anywhere. Justia publishes none, for any attorney — its contact form is the only email channel. Measured 0% on both samples. Anyone selling you "Justia emails" generated them somewhere else, usually by guessing patterns against the firm domain. What you get instead: contactFormUrl on 100% of rows, phone at 99.5–100%, and website at 99.5% / 67.9% to enrich from.
  • This is the claimed-profile subset of the directory, not the whole bar. It is a self-selected population — attorneys who registered and filled their profile in. If you need every admitted attorney including the ones who never marketed themselves, that is a bar-registry product, not a directory product; see the sibling table below.
  • rating is 30.9% / 4.3% filled. A missing rating means Justia published none, not that the scrape failed. Do not build a "top-rated attorney" product on this column.
  • awards is 73.2% in a metro and 17.1% statewide, languages 96.4% / 37.1%, otherDirectoryProfiles 74.1% / 35.7%. The metro numbers are a Premium-advertiser sample. The whole-state numbers are what an ordinary claimed profile looks like.
  • Roughly 1 in 4 profiles print no admission year at all (they print the bar organisation in that slot instead). yearAdmitted is null for those rather than guessed, and minYearsLicensed falls back to self-reported experience so the filter does not silently discard them.
  • It is paced, and you cannot buy your way out of it. The directory answers a burst with an HTTP 429 that carries no retry-after header and lasts minutes. Expect roughly 1,000 attorneys per 20 minutes. Raising maxConcurrency does not help.
  • No email, no login, no CAPTCHA-solving service, and no attempt at /organization/… firm pages. A profile URL without the trailing numeric id is rejected with an error naming it, rather than silently skipped.
  • US only. The directory lists US attorneys; there is no international coverage to return.

⚙️ How it works (technical)

  1. Your states, cities and practice areas are turned into directory listing URLs (/lawyers/{area}/{state}/{city}), one per combination.
  2. Each listing is paged until two consecutive pages add no new attorney, or maxPagesPerListing is reached — the pager keeps serving results rather than ending, so the streak is the real stop condition.
  3. Every /lawyer/{slug}-{id} link is collected and deduplicated on the numeric id before any profile is fetched.
  4. Each profile page is read twice over: the six ld+json blocks (name, firm, full address, every phone, lat/lon, socials, aggregate rating) and the HTML body (practice-area tree, jurisdictions, education, awards, associations, languages, fees, badges, websites).
  5. Filters are applied, rows are pushed and charged in the same call, and the run prints its own measured field fill.

Where the rows come from

The rows are served from lawyers.law.cornell.edu, the Justia-operated lawyer directory published with Cornell Law School's Legal Information Institute — the same Justia database and the same profile pages, with the same numeric profile ids. Every row carries its matching lawyers.justia.com URL in justiaProfileUrl, so you can open the Justia page for any lead.

lawyers.justia.com itself is behind a Cloudflare managed Turnstile challenge on every path, including /robots.txt and /sitemap.xml. Measured 2026-08-12: 0/15 fresh Apify RESIDENTIAL sessions, 0/4 Apify datacenter, 0/1 direct, 0/5 other proxy countries, and 0/1 with a real headless Chromium. This route is not a shortcut around a rate limit — it is where the data is actually reachable.

The transport ladder, measured

The LII host answers plain HTTP with an AWS WAF challenge (HTTP 202 + a 2 KB shell) on every path, including / and /robots.txt. Measured 2026-08-12, through Apify:

AttemptResult
got-scraping, no token202 challenge on every path
Solving the proof-of-work in pure Nodetoken issued but rejected — the site's own script posts a different payload, so a Node-minted token is treated exactly like no token at all
Headless Chromium, default user-agent403 (CloudFront rejects the HeadlessChrome UA outright, as it does curl/8.4.0 and the Googlebot UA)
Headless Chromium + a real Chrome UA200, full page, ~1.1 s to mint

So the Actor loads one page in a headless browser, lets the site's own challenge script issue the aws-waf-token cookie, and then crawls on ordinary HTTP requests carrying it. The token is bound to the exit IP and the user-agent, which is why the user-agent is pinned and why the browser and the crawl share one proxy session.

  • Sustained load: 18/18 = 100% over 18 contiguous listing pages on a single token.
  • Full validation run: 235/235 requests = 100% (14 listing pages + 221 profile pages) in 240 s, 0 failures, 0 rate-limit pauses, 1 token mint.
  • Token lifetime ~5 minutes (verified 200 at t+4 min, challenged at t+5 min). The Actor re-mints automatically whenever it is challenged, so long runs are unaffected.
  • Pacing: ~325 requests at concurrency 4 with no pacing earned a 429. The crawl therefore runs at about one request per second, a 429 pauses every worker rather than one, and the pace then eases permanently.

Because the challenge is cleared in a browser page load, the Actor needs 2 GB of memory. The browser is closed immediately afterwards; the crawl itself is plain HTTP, and runs direct with no proxy by default.

Duplicates — measured on contiguous page walks

Every city listing reprints its sponsored block on each page. Measured over pages 1–18 of /lawyers/texas/austin: 495 listed rows, 261 unique — a 47.3% duplicate rate at the listing level (30–39% on shorter walks). A second contiguous walk, on the Apify platform on 2026-08-13, over 20 pages of the same listing: 554 listed rows, 303 unique — 45.3%.

None of that reaches the dataset. Profile ids are deduplicated globally before anything is fetched, verified on both validation runs: 220/220 and 140/140 unique profile ids, 0.0% duplicates, unique names matching unique ids exactly.

Justia's own address casing is inconsistent, so city is title-cased only when Justia shouts it (SAN MARCOSSan Marcos, measured at 3.5% of rows; MCALLENMcAllen, O'FALLONO'Fallon; Macon is deliberately left alone), and two-letter state codes are upper-cased (MtMT, measured 132 vs 3 on one state crawl). Anything already mixed case is passed through exactly as published.

When a run fails

  • Zero rows throws. A run that quietly succeeds with no data is a bug, not a result. The error names the counts: profiles fetched, network failures, dead profiles, unparseable pages, and how many your own filters removed.
  • A markup change throws. If more than 20% of profile pages return HTTP 200 but no readable profile, the run fails rather than shipping a degraded extraction.
  • A listing that finds no attorney links at all throws, because that means the directory changed how it renders result cards — not that your filters were too narrow.
  • A bad city slug warns by name. The directory renders a page for a city that does not exist instead of returning 404, so a typo shows up as an empty first page and the log says which listing it was. States and practice areas cannot be misspelt — they are dropdowns.
  • A profile URL with no numeric id stops the run with the offending URL in the message.
  • Running out of candidates warns with how many were delivered against how many you asked for, and what to widen.

🔎 How this differs from our other attorney Actors

We build several attorney scrapers, and they are not substitutes. The ones already live are on our Apify Store profile; the rest are rolling out.

ActorWhat it isWhy you would use it instead
This oneJustia directory, all 50 states + DC + PR, claimed profilesMarketing-ready leads: phone at 99.5–100%, website, practice-area tree, paid-placement flag
ca-attorney-scraperThe California State Bar registryLicence status and bar-number verification for California — every admitted attorney, not the self-selected slice
state-bar-attorney-scraperThe New York Office of Court Administration registry — 293,648 registered attorneys plus 49,199 deceasedYou need every NY attorney, a licence status, or a firm-size cut (firmAttorneyCount). It carries no websites and no practice areas
martindale-lawyer-scraperMartindale-HubbellThe AV Preeminent peer rating and its sub-scores — a credential no directory listing carries
superlawyers-attorney-scraperSuper LawyersSelection years — who is on the list right now, and who just made it

Justia is where you go for the phone number and the practice areas. A state bar registry is where you go for completeness and licence status. Martindale is where you go for the peer rating. Running this Actor and a registry, then joining on name + city, gives you the registry's completeness with this one's contact depth.

❓ FAQ

Can I get the lawyer's email? No — and nobody honestly can from this source. Justia's public directory does not expose attorney email addresses for anyone; its contact form is the only email channel. Measured 0% across both samples. What you get instead is contactFormUrl on every row, phone at 99.5–100% and the firm website at 99.5% / 67.9%, which is the domain most buyers enrich against. Anyone selling "Justia emails" generated them elsewhere.

Does it need an account, a login or an API key? No. It reads public directory and profile pages only, and it does not log in anywhere.

Do I need a proxy? No. The Actor runs direct by default and clears the site's edge challenge itself — 235/235 requests clean on the last full validation run. Set Apify RESIDENTIAL only if token minting starts failing on your egress IP.

How many attorneys can I get from one state? More than you will want to pay for. The practical limit is your maxItems and your patience: the crawl is paced at about one request per second, so budget roughly 1,000 attorneys per 20 minutes.

Will two runs give me duplicates? Within a run, no — profile ids are deduplicated before fetching (220/220 and 140/140 unique on the validation runs). Across runs, overlapping scopes will overlap; dedupe on profileId, which is stable.

Do I get charged for rows my filters removed? No. Filters are applied after the profile page loads, so a filtered-out attorney costs the Actor a fetch and costs you nothing. You are billed per attorney delivered.

Why does an Austin crawl return Houston attorneys? Because the directory lists attorneys serving a city, drawn from the surrounding region. Each row's city/state is the attorney's real office — filter on that if you need strict geography.

Why is the rating out of 10? Because that is the scale Justia publishes. ratingScale is on every row so you never have to infer it, and only 30.9% (metro) / 4.3% (statewide) of profiles have a rating at all.

Can I scrape one specific attorney? Yes — paste their profile URL into Attorney profile URLs. Either lawyers.justia.com/lawyer/… or lawyers.law.cornell.edu/lawyer/… works; the trailing numeric id is what identifies them.

Can I schedule it? Yes, with an Apify Schedule. Attorney directory data moves slowly — a monthly or quarterly refresh is usually enough, and profileUrls lets you re-check a known list cheaply.

Will a run ever succeed with zero rows? No. Zero rows throws, with the scope and the HTTP counts in the message. A green-but-empty dataset is treated as a bug.

Something looks wrong — how do I debug it? Every run logs its own measured field fill, its duplicate rate, the number of challenge-token mints and the number of rate-limit pauses. Compare those to the numbers on this page; if they diverge, open an issue.

💬 Support & custom work

Found a missing field, or want a filter that is not here? Open an issue on the Issues tab. Custom fields, extra directories and scheduled feeds into your CRM or warehouse can be built on request.

⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Justia Inc., Cornell Law School or the Legal Information Institute. Justia® is a trademark of its owner. All trademarks are the property of their respective owners.

It reads only publicly available lawyer directory and profile pages — no authenticated endpoints, no login-only or private data, and no CAPTCHA-solving service. Attorney directory listings are published as public professional information. Rows describe real people: you are responsible for complying with Justia's terms, with applicable data-protection law (GDPR, CCPA and equivalents), with CAN-SPAM and telemarketing rules, and with the attorney advertising and solicitation rules of any bar you operate under. Honour opt-out and do-not-contact requests.

SEO Keywords

justia scraper, justia lawyer scraper, justia attorney scraper, justia lawyer directory scraper, lawyer directory scraper, attorney directory scraper, attorney leads scraper, lawyer leads scraper, attorney contact data, lawyer phone numbers, law firm leads, legal lead generation, scrape lawyers, scrape attorneys, attorney data extraction, practice area lawyer scraper, personal injury lawyer leads, criminal defense attorney list, us attorney dataset, law firm database, attorney phone list, legal directory data, lawyer prospecting list, attorney marketing data, justia lawyers export