Skip to main content

Enrichment Functions

Ten edge functions handle attorney and firm enrichment. The primary pipeline uses the Blitz API v2 for LinkedIn-based enrichment (email, phone, work history). Additional functions handle firm website URL detection and scraping.

Blitz API Functions

blitz-enrich-attorney-contacts

The primary enrichment function. Enriches email and phone for a batch of attorneys using the Blitz API v2.

Input

interface EnrichRequest {
attorneyIds: string[]; // UUIDs of attorneys to enrich
skipPhone?: boolean; // Skip phone enrichment (saves 5 credits/attorney)
skipEmail?: boolean; // Skip email enrichment
}

Flow

Blitz API v2 Endpoints

EndpointMethodCostInput Field
/v2/enrichment/emailPOST1 credit if foundperson_linkedin_url
/v2/enrichment/phonePOST5 credits if foundperson_linkedin_url
Field Name

The Blitz API v2 uses person_linkedin_url (NOT linkedin_profile_url). Using the wrong field name results in a 422 error.

Email Response Handling

interface BlitzEmailResponse {
email: string | null;
email_status: 'valid' | 'invalid' | 'catch_all' | 'unknown';
work_email: string | null;
all_emails: string[];
}
email_status Values

Only valid, invalid, catch_all, unknown are accepted. The value "unverified" does NOT exist and will cause an insert error.

Credit Costs

OperationCost
Email enrichment1 credit if found, 0 if not
Phone enrichment5 credits if found, 0 if not
Typical per attorney2-7 credits

blitz-update-sparse-attorneys

Updates attorney records that have incomplete data. Targets attorneys where key fields (email, phone, education) are missing.

Input

interface UpdateRequest {
firmId?: string; // Scope to a specific firm
limit?: number; // Max attorneys to process
}

Logic

  1. Query attorneys where email_primary IS NULL or phone_mobile IS NULL
  2. For each, call Blitz email and/or phone enrichment
  3. Update the record with new data

enrich-firm-attorneys

Bulk enrichment for all attorneys at a specific firm. Combines employee finding + email + phone enrichment.

Input

interface FirmEnrichRequest {
firmId: string;
maxAttorneys?: number; // Default 100
skipPhone?: boolean;
}

Flow

  1. Load firm's LinkedIn URL from firms table
  2. Call /v2/search/employee-finder with the firm's LinkedIn URL
  3. Filter results to valid attorney titles
  4. Enrich each with email and phone
  5. Upsert to attorneys table

URL Detection & Scraping Functions

detect-firm-url-patterns

Tests multiple URL pattern templates against a firm's website to find their attorney bio page format.

Input

interface DetectRequest {
firmId: string;
}

Logic

  1. Load 2 enriched attorneys from the firm (need real names to test)
  2. Test 37 URL patterns (e.g., /people/{first}-{last}, /lawyers/{last})
  3. Make HEAD requests to each generated URL
  4. If 200 OK, validate with a second attorney
  5. Save the working pattern to firms.profile_url_pattern

Known Patterns

FirmPattern
Most firms/people/{first}-{last}
Kirkland & Ellis/lawyers/{last_initial}/{last}-{first}
Gibson Dunn/lawyers/{last}
Latham & Watkins/people/{last}
Cleary Gottlieb/professionals/{first}-{last}
WilmerHale/bio/{first}-{last}

search-attorney-profile-urls

Uses the detected firm URL pattern to generate profile URLs for all attorneys at a firm.

Input

interface SearchUrlsRequest {
firmId: string;
limit?: number;
}

Flow

  1. Load firm's profile_url_pattern and website
  2. Load attorneys for the firm
  3. Generate URL for each attorney using the pattern
  4. Validate each URL with a HEAD request
  5. Store valid URLs in attorneys.firm_website_profile

find-attorney-urls

Alternative URL finder that uses search techniques rather than pattern matching. Useful for firms with non-standard URL patterns.


scrape-attorney-profiles

Web scraping function that extracts detailed attorney information from firm website bio pages. Populates the 34 website-scraping fields in the attorneys table.

Fields Extracted

  • Practice areas (primary, secondary, specialties)
  • Bar admissions (state and court)
  • Rankings (Chambers, Legal 500, Best Lawyers)
  • Awards and recognitions
  • Publications count
  • Office phone number
  • Education details (honors, major)
  • Representative matters
  • Languages

Side Effects

  • Updates up to 34 columns in attorneys
  • Sets website_scraped_at timestamp
  • Updates enrichment_level

match-profile-urls-to-attorneys

Links scraped firm website profiles to existing attorney records. Uses name matching to connect URLs found on firm websites to the corresponding attorneys rows.


populate-firm-websites

Backfills firms.website and firms.domain for firms that are missing this data. Uses the firm's LinkedIn URL to find their website.

Market Population Functions

populate-market

Creates or updates a market definition and links qualifying attorneys.

Input

interface PopulateMarketRequest {
marketId: string;
criteria: {
practiceArea?: string;
geography?: string;
seniority?: string;
firmTier?: string;
};
}

populate-market-attorneys

Links attorneys to a market based on the market's criteria. Queries the attorneys table using the market's filters and creates market_attorneys records.


preview-firm-attorneys

Returns a preview of attorneys at a firm that would be included in a market, without actually creating records. Used for UI previews before populating.