{
  "openapi": "3.0.1",
  "info": {
    "title": "Justia Lawyer Directory Scraper — Attorney Leads & Phones",
    "description": "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.",
    "version": "0.1",
    "x-build-id": "STW8MpCVonumPQnwU"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapersdelight~justia-lawyer-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapersdelight-justia-lawyer-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/scrapersdelight~justia-lawyer-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scrapersdelight-justia-lawyer-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/scrapersdelight~justia-lawyer-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scrapersdelight-justia-lawyer-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": {
          "states": {
            "title": "States",
            "type": "array",
            "description": "Pick one or more states. Every option here is a slug the directory itself publishes, so a picked state always exists. Each state is crawled as its own listing (×  each city, × each practice area), so three states with two practice areas is six listings.",
            "items": {
              "type": "string",
              "enum": [
                "alabama",
                "alaska",
                "arizona",
                "arkansas",
                "california",
                "colorado",
                "connecticut",
                "delaware",
                "district-of-columbia",
                "florida",
                "georgia",
                "hawaii",
                "idaho",
                "illinois",
                "indiana",
                "iowa",
                "kansas",
                "kentucky",
                "louisiana",
                "maine",
                "maryland",
                "massachusetts",
                "michigan",
                "minnesota",
                "mississippi",
                "missouri",
                "montana",
                "nebraska",
                "nevada",
                "new-hampshire",
                "new-jersey",
                "new-mexico",
                "new-york",
                "north-carolina",
                "north-dakota",
                "ohio",
                "oklahoma",
                "oregon",
                "pennsylvania",
                "puerto-rico",
                "rhode-island",
                "south-carolina",
                "south-dakota",
                "tennessee",
                "texas",
                "utah",
                "vermont",
                "virginia",
                "washington",
                "west-virginia",
                "wisconsin",
                "wyoming"
              ],
              "enumTitles": [
                "Alabama",
                "Alaska",
                "Arizona",
                "Arkansas",
                "California",
                "Colorado",
                "Connecticut",
                "Delaware",
                "District of Columbia",
                "Florida",
                "Georgia",
                "Hawaii",
                "Idaho",
                "Illinois",
                "Indiana",
                "Iowa",
                "Kansas",
                "Kentucky",
                "Louisiana",
                "Maine",
                "Maryland",
                "Massachusetts",
                "Michigan",
                "Minnesota",
                "Mississippi",
                "Missouri",
                "Montana",
                "Nebraska",
                "Nevada",
                "New Hampshire",
                "New Jersey",
                "New Mexico",
                "New York",
                "North Carolina",
                "North Dakota",
                "Ohio",
                "Oklahoma",
                "Oregon",
                "Pennsylvania",
                "Puerto Rico",
                "Rhode Island",
                "South Carolina",
                "South Dakota",
                "Tennessee",
                "Texas",
                "Utah",
                "Vermont",
                "Virginia",
                "Washington",
                "West Virginia",
                "Wisconsin",
                "Wyoming"
              ]
            }
          },
          "cities": {
            "title": "Cities (optional)",
            "type": "array",
            "description": "City slugs — lower case and hyphenated: austin, houston, new-york, los-angeles, san-francisco. Leave empty to crawl the whole state. Write a city as state/city — texas/austin, new-york/new-york — when you list several states, otherwise every city is tried in every state. A city listing returns attorneys SERVING that city, drawn from the surrounding region, so a texas/austin crawl legitimately returns Houston firms; each row's own city/state fields are the attorney's actual office. The directory renders a page for a city that does not exist instead of a 404, so a typo shows up as an empty first page and the run warns you by name.",
            "items": {
              "type": "string"
            }
          },
          "practiceAreas": {
            "title": "Practice areas (optional)",
            "type": "array",
            "description": "Pick one or more of the directory's 56 practice areas — these are its own slugs and titles, so nothing here can be misspelt. Leave empty to take every attorney in the state or city. Each area is crawled as a separate listing, so picking five areas in one city means five listings, not one; attorneys average 2.9 practice areas in a metro crawl and 3.7 in a whole-state crawl, so the areas overlap heavily and the deduplicator drops the repeats before you are billed.",
            "items": {
              "type": "string",
              "enum": [
                "personal-injury",
                "medical-malpractice",
                "criminal-law",
                "dui-dwi",
                "family-law",
                "divorce",
                "bankruptcy",
                "business-law",
                "consumer-law",
                "employment-law",
                "estate-planning",
                "foreclosure-defense",
                "immigration-law",
                "intellectual-property",
                "nursing-home-abuse",
                "probate",
                "products-liability",
                "real-estate-law",
                "tax-law",
                "traffic-tickets",
                "workers-compensation",
                "agricultural-law",
                "animal-dog-law",
                "antitrust-law",
                "appeals-appellate",
                "arbitration-mediation",
                "asbestos-mesothelioma",
                "cannabis-marijuana-law",
                "civil-rights",
                "collections",
                "communications-internet-law",
                "construction-law",
                "domestic-violence",
                "education-law",
                "elder-law",
                "energy-oil-gas-law",
                "entertainment-sports-law",
                "environmental-law",
                "government-administrative-law",
                "health-care-law",
                "insurance-claims",
                "insurance-defense",
                "international-law",
                "juvenile-law",
                "landlord-tenant",
                "legal-malpractice",
                "maritime-law",
                "military-law",
                "municipal-law",
                "native-american-law",
                "patents",
                "securities-law",
                "social-security-disability",
                "stockbroker-investment-fraud",
                "trademarks",
                "white-collar-crime"
              ],
              "enumTitles": [
                "Personal Injury",
                "Medical Malpractice",
                "Criminal Defense",
                "DUI & DWI",
                "Family Law",
                "Divorce",
                "Bankruptcy",
                "Business Law",
                "Consumer Law",
                "Employment Law",
                "Estate Planning",
                "Foreclosure Defense",
                "Immigration Law",
                "Intellectual Property",
                "Nursing Home Abuse",
                "Probate",
                "Products Liability",
                "Real Estate Law",
                "Tax Law",
                "Traffic Tickets",
                "Workers' Compensation",
                "Agricultural Law",
                "Animal & Dog Law",
                "Antitrust Law",
                "Appeals & Appellate",
                "Arbitration & Mediation",
                "Asbestos & Mesothelioma",
                "Cannabis & Marijuana Law",
                "Civil Rights",
                "Collections",
                "Communications & Internet Law",
                "Construction Law",
                "Domestic Violence",
                "Education Law",
                "Elder Law",
                "Energy, Oil & Gas Law",
                "Entertainment & Sports Law",
                "Environmental Law",
                "Gov & Administrative Law",
                "Health Care Law",
                "Insurance Claims",
                "Insurance Defense",
                "International Law",
                "Juvenile Law",
                "Landlord Tenant",
                "Legal Malpractice",
                "Maritime Law",
                "Military Law",
                "Municipal Law",
                "Native American Law",
                "Patents",
                "Securities Law",
                "Social Security Disability",
                "Stockbroker & Investment Fraud",
                "Trademarks",
                "White Collar Crime"
              ]
            }
          },
          "profileUrls": {
            "title": "Attorney profile URLs",
            "type": "array",
            "description": "One attorney per URL. Either host works — https://lawyers.justia.com/lawyer/jane-doe-123456 or https://lawyers.law.cornell.edu/lawyer/jane-doe-123456 — because the trailing numeric profile id is what identifies the attorney. A URL without that numeric id stops the run with an error naming the bad URL rather than silently skipping it. Duplicate ids are collapsed before anything is fetched, so pasting the same attorney twice costs you once.",
            "items": {
              "type": "string"
            }
          },
          "withPhoneOnly": {
            "title": "Only attorneys with a phone number",
            "type": "boolean",
            "description": "Keep only attorneys who publish a phone number. On by default because a lead with no phone and no email is not contactable — Justia publishes NO email address for any attorney, and its contact form is the only email channel (each row carries that form's URL). This filter costs you almost nothing: phone fill was measured at 99.5% on a 220-row metro sample and 100% on a 140-row whole-state sample.",
            "default": true
          },
          "withWebsiteOnly": {
            "title": "Only attorneys with a website",
            "type": "boolean",
            "description": "Keep only attorneys who link a firm website or blog — the domain you would enrich or run outbound against. Priced the same either way, but it costs coverage: website fill was 99.5% on the metro sample and 67.9% on the whole-state sample, so on a state crawl this discards about a third of the directory and the run fetches roughly three profiles for every two it keeps.",
            "default": false
          },
          "minYearsLicensed": {
            "title": "Minimum years licensed",
            "minimum": 0,
            "maximum": 80,
            "type": "integer",
            "description": "Keep only attorneys admitted to a bar at least this many years ago, computed from the earliest year in \"Jurisdictions Admitted to Practice\". Set 20+ for succession, retirement and M&A outreach; leave empty for everyone. About 1 in 4 profiles print the bar organisation (\"State Bar of Montana\") in that slot instead of a year, so this filter falls back to the attorney's self-reported years of experience rather than silently discarding them."
          },
          "includeCredentials": {
            "title": "Include credentials",
            "type": "boolean",
            "description": "Include the education, professional experience, awards, bar associations and certifications arrays. Turn off for a lean contact-only export. Measured fill on the metro sample: associations 95.9%, awards 73.2%; on the whole-state sample 84.3% and 17.1%.",
            "default": true
          },
          "includeReviewsMeta": {
            "title": "Include rating and review count",
            "type": "boolean",
            "description": "Include the aggregate client rating and its review count. The rating is out of 10, not out of 5 — ratingScale is on every row so you never have to guess. Only a minority of profiles carry one: measured 30.9% on the metro sample and 4.3% on the whole-state sample, so do not plan a run around it.",
            "default": true
          },
          "includeBiography": {
            "title": "Include the biography text",
            "type": "boolean",
            "description": "Include the attorney's full self-written biography — the copy you would personalise outreach from. It is long, so it is off by default. Measured fill: 96.8% on the metro sample, 64.3% on the whole-state sample.",
            "default": false
          },
          "maxItems": {
            "title": "Max attorneys",
            "minimum": 1,
            "type": "integer",
            "description": "Stop the run after this many attorneys have been delivered. 100 = $0.30, 1,000 = $3.00, 10,000 = $30.00. The crawl is paced at about one request per second (the directory rate-limits per IP), so budget roughly 1,000 attorneys per 20 minutes of run time.",
            "default": 100
          },
          "maxPagesPerListing": {
            "title": "Max listing pages per city or practice area",
            "minimum": 1,
            "maximum": 400,
            "type": "integer",
            "description": "How deep to page through each listing before moving to the next. Roughly 12-15 NEW attorneys per page after duplicates are removed — every listing page reprints its sponsored block, measured at a 47.3% duplicate rate over pages 1-18 of texas/austin. Raise it to go deeper in one city; add more cities or practice areas to go broader.",
            "default": 20
          },
          "maxConcurrency": {
            "title": "Concurrency",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "How many profile fetches may be in flight. Raising it will NOT make the run faster. The directory answers a burst with an HTTP 429 that carries no retry-after header and lasts minutes (measured: ~325 requests at concurrency 4 with no pacing tripped it), and the WAF token is pinned to one exit IP so we cannot rotate away from it — the Actor therefore paces itself at about one request per second whatever you put here. 2 is measured-optimal.",
            "default": 2
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Leave empty. This Actor runs direct, with no proxy, and clears the directory's edge challenge itself — measured 235/235 requests clean on a full validation run. Set Apify RESIDENTIAL only if your runs start failing to mint a token, in which case one pinned session is used for both the browser and the crawl, because the challenge token is bound to a single exit IP."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}