# finprodata Verified, never-stale contact + intelligence API for finance professionals (PE/VC investors, fund sponsors, registered advisers, brokers, LPs). Built from SEC Form ADV, Form D, FINRA BrokerCheck, and LP commitment filings. Every field carries source, last_verified_at, and confidence; staleness decays at read time, never in storage. Base URL: https://finprodata.vercel.app/v1 Auth: Authorization: Bearer Spec: https://finprodata.vercel.app/v1/openapi.json ## Endpoints | Method | Path | Description | Cost | |--------|---------------------------|--------------------------------------------------|---------| | GET | /health | Liveness check (no auth required) | FREE | | GET | /firms | Search firms by name, state, org_type, focus, AUM| FREE | | GET | /firms/{id} | Firm by UUID or crd:123456 | FREE | | GET | /people | Search people; contact values masked | FREE | | POST | /people/identify | Batch name resolution, up to 50 queries | FREE | | GET | /people/{id} | Person by UUID | FREE | | POST | /people/{id}/reveal | Reveal email/phone; costs 1 credit | 1 CREDIT| | POST | /exports/csv | Smartlead CSV of already-revealed contacts | FREE | | GET | /allocators | Search LPs: pensions, endowments, family offices | FREE | | GET | /network/{kind}/{id} | Connection graph for a firm or person | FREE | | GET | /usage | Monthly usage + remaining credits for this key | FREE | | GET | /openapi.json | OpenAPI 3.1 spec (no auth required) | FREE | | GET | /docs | Swagger UI (no auth required) | FREE | ## Endpoint details ### GET /firms Filters: q, state (2-letter), org_type (ria|era|broker_dealer|fund_sponsor), focus.investor_type (private_equity|venture_capital|hedge_fund|family_office| search_fund|independent_sponsor|investment_bank|business_broker|ma_advisor| lender|ria_wealth|endowment_foundation), aum_min, aum_max, limit (max 100), cursor. ### POST /people/identify Body: { queries: [{name, firm?, state?, title?}] } (max 50 per call — batch, never loop). Response per query: match_found, auto_match, total_matches, candidates[]. match_found=false means the person is not in the dataset; stop, do not fabricate. auto_match=true means the server judged one candidate unambiguous; use it. auto_match=false with multiple candidates: present differentiators to the user, never pick silently. ### POST /people/{id}/reveal Body: { channels: ["email"], max_age_days?: number } Costs 1 credit unless a fresh reveal is cached within 90 days (then units_spent: 0). Idempotent; safe to retry within the cache window. ### GET /network/{kind}/{id} kind: firm | person ## Agent guidance - Always call POST /people/identify before revealing contacts; it's free and prevents wasted credits. - Batch identify calls up to 50 queries per request; never loop one-by-one. - match_found=false is final. Do not proceed to reveal or fabricate a record. - total_matches is authoritative; never count visible candidates. - data_age_days is computed server-side; do not compute date math on raw dates. - Check GET /usage before bulk reveals to confirm credit headroom. - Filter firms by focus.investor_type + state + aum range before revealing; reveal is the only paid step. - Every contact/employment/focus field carries { source, last_verified_at, confidence }. Registry sources (adv_schedule_ab, form_d, brokercheck) are authoritative. ## Error handling Errors follow RFC 7807 (Content-Type: application/problem+json). Machine-actionable fields: type, title, detail, retry_after, budget_usd, suggestion. - 401 — missing or invalid API key - 402 — credit budget exhausted; do not retry until the cap resets - 400 — validation error; fix the request - 429 — rate limited; back off for Retry-After seconds - 5xx — transient; exponential backoff with jitter, max 3 retries ## Data coverage Sources: SEC Form ADV (Schedule A/B), SEC Form D, FINRA BrokerCheck, LP commitment filings, foundation 990s, accelerator/SBIC registries. Coverage: ~500k finance professionals, ~100k firms across the US.