Skip to content

Firmhound API Documentation

Base URL: https://api.firmhound.com

Note: All traffic is routed through Cloudflare for DDoS protection and TLS termination.

Search 23,000+ fund managers and 78,000+ private funds via REST API.

Quick Start

1. Get an API Key

First, create an account and generate an API key:

bash
# Register an account
curl -X POST "https://api.firmhound.com/v1/auth/register" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "you@example.com",
    "password": "your-secure-password",
    "full_name": "Your Name"
  }'

# Login to get JWT token
curl -X POST "https://api.firmhound.com/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "you@example.com",
    "password": "your-secure-password"
  }'

Response:

json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "user": {
    "id": 123,
    "email": "you@example.com",
    "tier": "starter"
  }
}

2. Create an API Key

bash
curl -X POST "https://api.firmhound.com/v1/api-keys" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Production Key",
    "tier": "starter"
  }'

Response:

json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "key": "fh_live_AbCd1234EfGh5678IjKl9012MnOp3456QrSt7890UvWxYz",
  "warning": "Save this key now - it will not be shown again"
}

⚠️ SAVE THE KEY NOW - You cannot retrieve it later!

3. Make Your First Request

bash
curl "https://api.firmhound.com/v1/gps?strategy=buyout&limit=5" \
  -H "Authorization: Bearer fh_live_AbCd1234EfGh5678IjKl9012MnOp3456QrSt7890UvWxYz"

Response:

json
{
  "data": [
    {
      "crd": "123456",
      "legal_name": "Example Capital Partners",
      "city": "New York",
      "state": "NY",
      "total_aum": 5000000000,
      "primary_strategy": "buyout",
      "employee_count": 150
    }
  ],
  "meta": {
    "total": 1,
    "limit": 5,
    "offset": 0
  }
}

Authentication

All API requests (except health checks) require authentication using an API key.

Method: Bearer token in the Authorization header

Authorization: Bearer fh_live_AbCd1234EfGh5678IjKl9012MnOp3456QrSt7890UvWxYz

API Key Format

  • Prefix: fh_live_ (production) or fh_test_ (development)
  • Length: 52 characters
  • Encoding: Base58 (alphanumeric, no ambiguous characters)

Rate Limits by Tier

TierRequests/DayBest For
Starter100Testing, small projects
Growth10,000Production apps
ScaleUnlimitedEnterprise use

Rate limit headers (returned with each response):

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 2025-12-12T00:00:00Z

Session Management

Manage active login sessions across devices.

GET /v1/auth/sessions

List all active sessions for the authenticated user.

Request:

bash
curl "https://api.firmhound.com/v1/auth/sessions" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response:

json
{
  "sessions": [
    {
      "id": "sess_abc123def456",
      "device": "Chrome on macOS",
      "ip_address": "192.168.1.100",
      "location": "New York, NY",
      "created_at": "2025-12-10T08:30:00Z",
      "last_active": "2025-12-12T14:22:00Z",
      "is_current": true
    },
    {
      "id": "sess_xyz789ghi012",
      "device": "Firefox on Windows",
      "ip_address": "192.168.1.101",
      "location": "New York, NY",
      "created_at": "2025-12-09T12:15:00Z",
      "last_active": "2025-12-11T18:45:00Z",
      "is_current": false
    }
  ],
  "total": 2
}

DELETE /v1/auth/sessions/{id}

Terminate a specific session.

Path Parameters:

  • id (string, required): Session ID to terminate

Request:

bash
curl -X DELETE "https://api.firmhound.com/v1/auth/sessions/sess_xyz789ghi012" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response:

json
{
  "message": "Session terminated successfully",
  "session_id": "sess_xyz789ghi012"
}

DELETE /v1/auth/sessions

Sign out all other devices (terminate all sessions except current).

Request:

bash
curl -X DELETE "https://api.firmhound.com/v1/auth/sessions" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response:

json
{
  "message": "All other sessions terminated successfully",
  "sessions_terminated": 3
}

Email Verification

Verify email addresses for new accounts.

POST /v1/auth/verify-email

Verify email address using the token sent to user's email.

Request:

bash
curl -X POST "https://api.firmhound.com/v1/auth/verify-email" \
  -H "Content-Type: application/json" \
  -d '{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }'

Response (200 OK):

json
{
  "message": "Email verified successfully",
  "email": "you@example.com",
  "verified_at": "2025-12-12T15:30:00Z"
}

Error Response (400 Bad Request - Invalid/Expired Token):

json
{
  "detail": "Invalid or expired verification token"
}

Error Response (409 Conflict - Already Verified):

json
{
  "detail": "Email already verified"
}

POST /v1/auth/resend-verification

Resend verification email to user's email address.

Request:

bash
curl -X POST "https://api.firmhound.com/v1/auth/resend-verification" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response:

json
{
  "message": "Verification email sent",
  "email": "you@example.com",
  "sent_at": "2025-12-12T15:35:00Z"
}

Error Response (409 Conflict - Already Verified):

json
{
  "detail": "Email already verified"
}

Error Response (429 Too Many Requests - Rate Limited):

json
{
  "detail": "Please wait before requesting another verification email"
}

Unified Account Model

Firmhound uses a unified account system across both the web application (app.firmhound.com) and the developer API (developers.firmhound.com).

Key Concepts

Single Account, Dual Tiers:

  • The same email/password credentials work on both platforms
  • Users have two independent tier settings:
    • subscription_plan: Controls access to the web application (App)
    • api_tier: Controls API rate limits and features (API)
  • These tiers can be different (e.g., Pro subscription with Starter API tier)

Account Information

GET /v1/auth/me

Get current user information including both subscription plan and API tier.

Request:

bash
curl "https://api.firmhound.com/v1/auth/me" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response:

json
{
  "id": 123,
  "email": "you@example.com",
  "full_name": "Your Name",
  "subscription_plan": "pro",
  "api_tier": "starter",
  "email_verified": true,
  "created_at": "2025-11-15T10:00:00Z"
}

Field Descriptions:

  • subscription_plan: App access tier (free, starter, pro, enterprise)
  • api_tier: API access tier (starter, growth, scale)
  • email_verified: Whether the user has verified their email address

Tier Independence

The subscription_plan and api_tier fields operate independently:

Scenariosubscription_planapi_tierApp AccessAPI Access
App-only userprostarterFull Pro features100 req/day
API-only userfreegrowthBasic app access10,000 req/day
Full accessenterprisescaleAll app featuresUnlimited API

Upgrading Tiers

  • App subscription: Upgrade via app.firmhound.com/settings/billing
  • API tier: Upgrade via developers.firmhound.com/billing or contact sales

Each tier can be managed independently without affecting the other.


Endpoints Reference

Health & Statistics

GET /health

Health check with database connectivity validation.

Request:

bash
curl "https://api.firmhound.com/health"

Response (200 OK):

json
{
  "status": "healthy",
  "service": "Firmhound API",
  "version": "1.0.0",
  "timestamp": "2025-12-11T12:00:00.000Z",
  "checks": {
    "database": "connected"
  }
}

Response (503 Service Unavailable - database down):

json
{
  "status": "unhealthy",
  "service": "Firmhound API",
  "version": "1.0.0",
  "timestamp": "2025-12-11T12:00:00.000Z",
  "checks": {
    "database": "unreachable"
  }
}

GET /v1/stats

Get database statistics and counts.

Request:

bash
curl "https://api.firmhound.com/v1/stats"

Response:

json
{
  "data": {
    "total_advisers": 23456,
    "total_funds": 78901,
    "total_canonical_gps": 15234,
    "advisers_with_funds": 12345,
    "unique_strategies": 25,
    "unique_states": 52
  },
  "meta": {
    "timestamp": "2025-12-11T12:00:00.000Z"
  }
}

Fund Managers (GPs)

GET /v1/gps

Search fund managers with 15+ filters.

Query Parameters:

ParameterTypeDescriptionExample
qstringSearch query (name, location)blackstone
strategystringPrimary strategybuyout, venture, real-estate
min_aumintegerMinimum AUM (USD)1000000000 (1B)
max_aumintegerMaximum AUM (USD)10000000000 (10B)
statestringUS state codeNY, CA, TX
countrystringCountryUnited States, United Kingdom
min_employeesintegerMinimum employee count50
max_employeesintegerMaximum employee count500
has_fundsbooleanOnly GPs with fundstrue
limitintegerResults per page (1-100)20
offsetintegerPagination offset0
sortstringSort fieldaum, name, employees
orderstringSort orderdesc, asc

Request:

bash
curl "https://api.firmhound.com/v1/gps?strategy=buyout&min_aum=1000000000&state=NY&limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "data": [
    {
      "crd": "123456",
      "legal_name": "Example Capital Partners LP",
      "city": "New York",
      "state": "NY",
      "country": "United States",
      "total_aum": 15000000000,
      "primary_strategy": "buyout",
      "employee_count": 250,
      "fund_count": 8,
      "canonical_gp_id": 789,
      "website": "https://example-capital.com"
    }
  ],
  "meta": {
    "total": 45,
    "limit": 10,
    "offset": 0,
    "filters_applied": {
      "strategy": "buyout",
      "min_aum": 1000000000,
      "state": "NY"
    }
  }
}

GET /v1/gps/{crd}

Get detailed information about a specific fund manager.

Path Parameters:

  • crd (string, required): SEC Central Registration Depository number

Request:

bash
curl "https://api.firmhound.com/v1/gps/123456" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "data": {
    "crd": "123456",
    "legal_name": "Example Capital Partners LP",
    "city": "New York",
    "state": "NY",
    "country": "United States",
    "total_aum": 15000000000,
    "primary_strategy": "buyout",
    "employee_count": 250,
    "fund_count": 8,
    "canonical_gp_id": 789,
    "website": "https://example-capital.com",
    "phone": "+1-212-555-0100",
    "founded_year": 1995
  }
}

Error Response (404 Not Found):

json
{
  "detail": "Fund manager with CRD 123456 not found"
}

GET /v1/gps/{crd}/funds

Get all funds managed by a specific GP.

Request:

bash
curl "https://api.firmhound.com/v1/gps/123456/funds" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "data": [
    {
      "id": 1001,
      "fund_id": "F123456789",
      "name": "Example Capital Fund IV LP",
      "vintage_year": 2020,
      "gross_asset_value": 2500000000,
      "strategy": "buyout",
      "is_3c1": true,
      "is_3c7": false
    },
    {
      "id": 1002,
      "fund_id": "F987654321",
      "name": "Example Capital Fund V LP",
      "vintage_year": 2023,
      "gross_asset_value": 3500000000,
      "strategy": "buyout",
      "is_3c1": false,
      "is_3c7": true
    }
  ],
  "meta": {
    "gp_crd": "123456",
    "gp_name": "Example Capital Partners LP",
    "total_funds": 2,
    "total_gav": 6000000000
  }
}

GET /v1/gps/{crd}/stats

Get aggregate statistics for a GP's fund portfolio.

Request:

bash
curl "https://api.firmhound.com/v1/gps/123456/stats" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "data": {
    "total_funds": 8,
    "total_gav": 12500000000,
    "avg_fund_size": 1562500000,
    "oldest_vintage": 2005,
    "newest_vintage": 2023,
    "strategies": ["buyout", "growth equity"],
    "fund_3c1_count": 3,
    "fund_3c7_count": 5
  }
}

GET /v1/gps/{crd}/regulatory

Get regulatory events and disclosures from FINRA BrokerCheck.

Pricing: $0.50/request (flat fee) Cache: 24-hour TTL, use force_refresh=true to bypass

Query Parameters:

ParameterTypeDefaultDescription
event_typestringallFilter: disciplinary, regulatory, civil, all
after_datedate-Only events after this date (YYYY-MM-DD)
force_refreshbooleanfalseBypass cache and fetch fresh from BrokerCheck

Request:

bash
curl "https://api.firmhound.com/v1/gps/123456/regulatory" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Filter by event type
curl "https://api.firmhound.com/v1/gps/123456/regulatory?event_type=disciplinary" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "data": {
    "crd": "123456",
    "firm_name": "Example Capital Partners LP",
    "events": [
      {
        "event_type": "regulatory",
        "event_date": "2023-05-15",
        "description": "Consent agreement with state regulator",
        "resolution": "Fine paid, no admission of wrongdoing",
        "disclosed_at": "2023-06-01",
        "source": "BrokerCheck"
      }
    ],
    "total_events": 1,
    "last_checked": "2025-12-12T10:30:00Z"
  },
  "meta": {
    "source": "FINRA BrokerCheck",
    "cache_status": "hit",
    "cache_expires": "2025-12-13T10:30:00Z"
  }
}

Event Types:

  • disciplinary: Internal firm disciplinary actions
  • regulatory: SEC, FINRA, state regulator actions
  • civil: Civil court proceedings
  • criminal: Criminal proceedings (rare)

GET /v1/gps/{crd}/amendments

Get ADV filing amendment history for a GP.

Pricing: $0.25/request (flat fee)

Query Parameters:

ParameterTypeDefaultMaxDescription
limitinteger50100Max amendments to return

Request:

bash
curl "https://api.firmhound.com/v1/gps/123456/amendments?limit=25" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "data": [
    {
      "accession_number": "0001234567-24-000123",
      "filing_type": "ADV/A",
      "filing_date": "2024-03-15",
      "amendment_type": "annual",
      "processed_at": "2024-03-16T10:30:00Z",
      "status": "completed"
    }
  ],
  "meta": {
    "total": 25,
    "crd": "123456",
    "pricing": {
      "cost": 0.25,
      "description": "Flat fee per request"
    }
  }
}

Amendment Types:

  • initial: First ADV filing (registration)
  • annual: Annual update (typically Jan-Mar)
  • material: Material change outside annual cycle
  • withdrawal: ADV-W withdrawal filing

GET /v1/gps/{crd}/changes

Get derived field changes over time for a GP.

Pricing: $0.25/request (flat fee)

Tracks changes in key metrics between filings: AUM, employees, strategy, location.

Query Parameters:

ParameterTypeDefaultMaxDescription
limitinteger50100Max change records to return

Request:

bash
curl "https://api.firmhound.com/v1/gps/123456/changes" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "data": [
    {
      "filing_date": "2024-03-15",
      "fields_changed": [
        {
          "field": "total_aum",
          "before": 500000000,
          "after": 750000000,
          "change_amount": 250000000,
          "change_percent": 50.0
        }
      ]
    }
  ],
  "meta": {
    "total": 10,
    "crd": "123456",
    "pricing": {
      "cost": 0.25,
      "description": "Flat fee per request"
    }
  }
}

GET /v1/gps/{crd}/metrics

Get derived analytics and computed metrics for a GP.

Pricing: $0.15/request (flat fee)

Request:

bash
curl "https://api.firmhound.com/v1/gps/123456/metrics" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "gp": {
    "crd": "123456",
    "legal_name": "Example Capital Partners",
    "total_aum": 5000000000,
    "employee_count": 50
  },
  "metrics": {
    "aum_growth": {
      "yoy_percent": 15.5,
      "cagr_3y_percent": 12.3
    },
    "fund_metrics": {
      "fund_count": 8,
      "avg_fund_size_usd": 625000000,
      "avg_fund_size_trend_percent": 10.5,
      "fund_launch_cadence_months": 18.0,
      "first_vintage": 2010,
      "latest_vintage": 2024
    },
    "employee_growth": {
      "yoy_percent": 8.0
    }
  },
  "meta": {
    "calculated_at": "2025-12-12T12:00:00Z",
    "data_sources": ["advisers", "private_funds", "processed_filings"]
  }
}

Metrics Explained:

  • aum_growth.yoy_percent: Year-over-year AUM growth
  • aum_growth.cagr_3y_percent: 3-year compound annual growth rate
  • fund_launch_cadence_months: Average months between fund launches
  • avg_fund_size_trend_percent: Recent funds vs earlier funds size comparison

Find similar GPs based on configurable similarity factors.

Pricing: $0.15/request (flat fee)

Query Parameters:

ParameterTypeDefaultDescription
similarity_factorsstringstrategy,aum_band,geographyComma-separated factors
limitinteger10Max similar GPs (1-25)

Similarity Factors:

  • strategy: Same primary strategy (40 pts)
  • aum_band: Similar AUM range ±50% (30 pts)
  • geography: Same state/country (20 pts)
  • fund_count: Similar fund count ±30% (10 pts)

Request:

bash
curl "https://api.firmhound.com/v1/gps/123456/related?similarity_factors=strategy,geography&limit=5" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "source_gp": {
    "crd": "123456",
    "legal_name": "Example Capital",
    "strategy": "private_equity",
    "aum": 5000000000,
    "location": "New York, United States",
    "fund_count": 8
  },
  "similar_gps": [
    {
      "crd": "67890",
      "legal_name": "Similar Partners",
      "strategy": "private_equity",
      "aum": 4500000000,
      "location": "New York, United States",
      "fund_count": 7,
      "similarity_score": 90,
      "similarity_breakdown": {
        "score": 90,
        "reasons": ["same strategy", "similar AUM", "same location"]
      }
    }
  ],
  "meta": {
    "similarity_factors": ["strategy", "aum_band", "geography"],
    "max_score": 90,
    "calculated_at": "2025-12-12T12:00:00Z"
  }
}

GET /v1/gps/{crd}/team

Get current team members for a GP with People Data Labs enrichment.

Cost Protection: Default limit of 50 people, max 100 to prevent runaway costs on mega-firms. Pricing: $0.50 per person enriched.

Query Parameters:

ParameterTypeDefaultMaxDescription
limitinteger50100Number of team members to return
rolestringall-Filter: partner, md, vp, associate, other
sortstringseniority-Sort by seniority (most senior first)

Request Examples:

bash
# Get top 50 team members (default)
curl "https://api.firmhound.com/v1/gps/123456/team" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Filter by role
curl "https://api.firmhound.com/v1/gps/123456/team?role=partner" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Request more people (up to 100)
curl "https://api.firmhound.com/v1/gps/123456/team?limit=100" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "data": [
    {
      "id": "person_123",
      "full_name": "John Smith",
      "title": "Managing Partner",
      "role": "partner",
      "seniority_level": "executive",
      "linkedin_url": "https://linkedin.com/in/...",
      "location": "New York, NY",
      "tenure_years": 15
    },
    {
      "id": "person_124",
      "full_name": "Jane Doe",
      "title": "Vice President",
      "role": "vp",
      "seniority_level": "senior",
      "linkedin_url": "https://linkedin.com/in/...",
      "location": "San Francisco, CA",
      "tenure_years": 8
    }
  ],
  "meta": {
    "returned": 50,
    "total_available": 247,
    "has_more": true,
    "next_page_cost": "$25.00",
    "filters_applied": {
      "limit": 50,
      "role": "all",
      "sort": "seniority"
    }
  }
}

Cost Protection Examples:

For a mega-firm like Blackstone (5,000+ employees):

GET /v1/gps/148826/team              → Returns top 50 by seniority  = $25.00
GET /v1/gps/148826/team?role=partner → Returns ~40 partners         = $20.00
GET /v1/gps/148826/team?limit=100    → Returns top 100              = $50.00 (max)

Response Metadata:

  • returned: Number of people in current response
  • total_available: Total team members for this GP
  • has_more: Boolean indicating if more people exist beyond limit
  • next_page_cost: Estimated cost to retrieve next page (same limit)

Private Funds

GET /v1/funds

Search private funds with multiple filters.

Query Parameters:

ParameterTypeDescriptionExample
qstringSearch fund nameopportunity
strategystringInvestment strategybuyout, venture
min_vintageintegerMinimum vintage year2015
max_vintageintegerMaximum vintage year2023
min_gavintegerMinimum GAV (USD)100000000
max_gavintegerMaximum GAV (USD)5000000000
is_3c1booleanSEC Rule 3(c)(1) fundstrue
is_3c7booleanSEC Rule 3(c)(7) fundstrue
limitintegerResults per page (1-100)20
offsetintegerPagination offset0

Request:

bash
curl "https://api.firmhound.com/v1/funds?strategy=venture&min_vintage=2020&limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "data": [
    {
      "id": 2001,
      "fund_id": "F555666777",
      "name": "Innovation Ventures Fund III LP",
      "adviser_crd": "654321",
      "adviser_name": "Innovation Ventures LLC",
      "vintage_year": 2021,
      "gross_asset_value": 450000000,
      "strategy": "venture",
      "is_3c1": false,
      "is_3c7": true
    }
  ],
  "meta": {
    "total": 127,
    "limit": 10,
    "offset": 0,
    "filters_applied": {
      "strategy": "venture",
      "min_vintage": 2020
    }
  }
}

GET /v1/funds/{fund_id}

Get detailed information about a specific fund.

Path Parameters:

  • fund_id (string, required): Fund ID (805-XXXXXXXXXX format)

Request:

bash
curl "https://api.firmhound.com/v1/funds/2001" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "data": {
    "id": 2001,
    "fund_id": "F555666777",
    "name": "Innovation Ventures Fund III LP",
    "adviser_crd": "654321",
    "adviser_name": "Innovation Ventures LLC",
    "vintage_year": 2021,
    "gross_asset_value": 450000000,
    "strategy": "venture",
    "is_3c1": false,
    "is_3c7": true,
    "beneficial_owners_count": 85
  }
}

GET /v1/funds/{fund_id}/amendments

Get amendment history for a private fund.

Pricing: $0.25/request (flat fee)

Query Parameters:

ParameterTypeDefaultMaxDescription
limitinteger50100Max amendments to return

Request:

bash
curl "https://api.firmhound.com/v1/funds/805-1234567890/amendments" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "data": [
    {
      "accession_number": "0001234567-24-000123",
      "filing_type": "ADV/A",
      "filing_date": "2024-03-15",
      "amendment_type": "annual",
      "processed_at": "2024-03-16T10:30:00Z"
    }
  ],
  "meta": {
    "total": 15,
    "fund_id": "805-1234567890",
    "adviser_crd": "123456",
    "pricing": {
      "cost": 0.25,
      "description": "Flat fee per request"
    }
  }
}

Unified search across both GPs and funds.

Query Parameters:

ParameterTypeDescriptionExample
qstring (required)Search query (min 2 chars)blackstone
typesstringComma-separated typesgp,fund
limitintegerResults per type (1-20)5

Request:

bash
curl "https://api.firmhound.com/v1/search?q=apollo&types=gp,fund&limit=5" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "data": {
    "gps": [
      {
        "id": "gp_123456",
        "crd": "123456",
        "name": "Apollo Global Management",
        "location": "New York, NY",
        "aum": 50000000000,
        "canonical_id": 101,
        "type": "gp"
      }
    ],
    "funds": [
      {
        "id": 3001,
        "fund_id": "F111222333",
        "name": "Apollo Investment Fund IX LP",
        "adviser": "Apollo Global Management",
        "vintage_year": 2020,
        "type": "fund"
      }
    ]
  },
  "meta": {
    "query": "apollo",
    "gp_count": 1,
    "fund_count": 1
  }
}

GET /v1/search/autocomplete

Fast typeahead suggestions for search UI.

Query Parameters:

ParameterTypeDescriptionExample
qstring (required)Partial query (min 2 chars)apol
typestringFilter by typegp, fund, all
limitintegerMax suggestions (1-20)10

Request:

bash
curl "https://api.firmhound.com/v1/search/autocomplete?q=apol&limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "data": [
    {
      "text": "Apollo Global Management",
      "type": "gp",
      "id": "gp_123456",
      "metadata": {
        "crd": "123456",
        "location": "New York, NY"
      }
    },
    {
      "text": "Apollo Investment Fund IX LP",
      "type": "fund",
      "id": 3001,
      "metadata": {
        "vintage_year": 2020
      }
    }
  ],
  "meta": {
    "query": "apol",
    "count": 2
  }
}

GET /v1/search/aggregate

Get market-level aggregations across GPs and funds.

Pricing: $0.15/request (flat fee)

Query Parameters:

ParameterTypeRequiredDescription
group_bystringYesstrategy, vintage, geography, aum_band
countrystringNoFilter by country
strategystringNoFilter by strategy
min_aumintegerNoFilter by minimum AUM
min_vintageintegerNoFilter by minimum vintage year
max_vintageintegerNoFilter by maximum vintage year

Aggregation Types:

  • strategy: AUM and GP count by primary strategy
  • vintage: Fund count and AUM by vintage year
  • geography: GP count and AUM by state/country
  • aum_band: GP distribution by AUM bands (<100M, 100M-500M, 500M-1B, 1B-10B, >10B)

Request Examples:

bash
# Aggregate by strategy
curl "https://api.firmhound.com/v1/search/aggregate?group_by=strategy" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Aggregate by vintage with strategy filter
curl "https://api.firmhound.com/v1/search/aggregate?group_by=vintage&strategy=venture_capital" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Aggregate by geography for US only
curl "https://api.firmhound.com/v1/search/aggregate?group_by=geography&country=United States" \
  -H "Authorization: Bearer YOUR_API_KEY"

# AUM band distribution
curl "https://api.firmhound.com/v1/search/aggregate?group_by=aum_band&min_aum=100000000" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (strategy):

json
{
  "aggregation_type": "strategy",
  "data": [
    {
      "strategy": "private_equity",
      "gp_count": 1250,
      "total_aum": 500000000000,
      "avg_aum": 400000000,
      "fund_count": 4800
    },
    {
      "strategy": "venture_capital",
      "gp_count": 800,
      "total_aum": 150000000000,
      "avg_aum": 187500000,
      "fund_count": 3200
    }
  ],
  "meta": {
    "filters": {"country": "United States"},
    "calculated_at": "2025-12-12T12:00:00Z"
  }
}

Response (vintage):

json
{
  "aggregation_type": "vintage",
  "data": [
    {
      "vintage_year": 2024,
      "fund_count": 125,
      "total_gav": 75000000000,
      "avg_fund_size": 600000000
    }
  ],
  "meta": {
    "filters": {"strategy": "venture_capital"},
    "calculated_at": "2025-12-12T12:00:00Z"
  }
}

Response (geography):

json
{
  "aggregation_type": "geography",
  "data": [
    {
      "country": "United States",
      "state": "New York",
      "location": "New York, United States",
      "gp_count": 350,
      "total_aum": 250000000000,
      "avg_aum": 714285714
    }
  ],
  "meta": {
    "filters": {},
    "calculated_at": "2025-12-12T12:00:00Z"
  }
}

Response (aum_band):

json
{
  "aggregation_type": "aum_band",
  "data": [
    {"aum_band": "<100M", "gp_count": 2500, "total_aum": 125000000000},
    {"aum_band": "100M-500M", "gp_count": 1200, "total_aum": 360000000000},
    {"aum_band": "500M-1B", "gp_count": 620, "total_aum": 450000000000},
    {"aum_band": "1B-10B", "gp_count": 425, "total_aum": 1200000000000},
    {"aum_band": ">10B", "gp_count": 85, "total_aum": 1500000000000}
  ],
  "meta": {
    "filters": {},
    "calculated_at": "2025-12-12T12:00:00Z"
  }
}

Reference Data

GET /v1/strategies

List all available investment strategies with counts.

Request:

bash
curl "https://api.firmhound.com/v1/strategies"

Response:

json
{
  "data": [
    {
      "strategy": "buyout",
      "count": 5432
    },
    {
      "strategy": "venture",
      "count": 3210
    },
    {
      "strategy": "real-estate",
      "count": 2100
    }
  ]
}

GET /v1/locations

List states and countries with GP counts.

Request:

bash
curl "https://api.firmhound.com/v1/locations"

Response:

json
{
  "data": {
    "states": [
      {
        "state": "NY",
        "count": 4521
      },
      {
        "state": "CA",
        "count": 3876
      }
    ],
    "countries": [
      {
        "country": "United States",
        "count": 18234
      },
      {
        "country": "United Kingdom",
        "count": 1987
      }
    ]
  }
}

Code Examples

Python

python
import requests
import os

class FirmhoundClient:
    def __init__(self, api_key):
        self.base_url = "https://api.firmhound.com"
        self.headers = {"Authorization": f"Bearer {api_key}"}

    def search_gps(self, **filters):
        """Search fund managers with filters."""
        response = requests.get(
            f"{self.base_url}/v1/gps",
            headers=self.headers,
            params=filters
        )
        response.raise_for_status()
        return response.json()

    def get_gp(self, crd):
        """Get GP details by CRD number."""
        response = requests.get(
            f"{self.base_url}/v1/gps/{crd}",
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()

    def get_gp_funds(self, crd):
        """Get all funds for a GP."""
        response = requests.get(
            f"{self.base_url}/v1/gps/{crd}/funds",
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()

# Usage
api_key = os.getenv("FUNDSEARCH_API_KEY")
client = FirmhoundClient(api_key)

# Search buyout firms in NY with $1B+ AUM
results = client.search_gps(
    strategy="buyout",
    state="NY",
    min_aum=1_000_000_000,
    limit=10
)

print(f"Found {results['meta']['total']} fund managers")
for gp in results['data']:
    print(f"- {gp['legal_name']}: ${gp['total_aum']:,.0f} AUM")

JavaScript / Node.js

javascript
const axios = require('axios');

class FirmhoundClient {
  constructor(apiKey) {
    this.baseURL = 'https://api.firmhound.com';
    this.apiKey = apiKey;
  }

  async searchGPs(filters) {
    const response = await axios.get(`${this.baseURL}/v1/gps`, {
      headers: { Authorization: `Bearer ${this.apiKey}` },
      params: filters
    });
    return response.data;
  }

  async getGP(crd) {
    const response = await axios.get(`${this.baseURL}/v1/gps/${crd}`, {
      headers: { Authorization: `Bearer ${this.apiKey}` }
    });
    return response.data;
  }

  async getGPFunds(crd) {
    const response = await axios.get(`${this.baseURL}/v1/gps/${crd}/funds`, {
      headers: { Authorization: `Bearer ${this.apiKey}` }
    });
    return response.data;
  }
}

// Usage
const client = new FirmhoundClient(process.env.FUNDSEARCH_API_KEY);

(async () => {
  const results = await client.searchGPs({
    strategy: 'venture',
    state: 'CA',
    min_aum: 500_000_000,
    limit: 10
  });

  console.log(`Found ${results.meta.total} fund managers`);
  results.data.forEach(gp => {
    console.log(`- ${gp.legal_name}: $${gp.total_aum.toLocaleString()} AUM`);
  });
})();

cURL

bash
#!/bin/bash

API_KEY="fh_live_YourApiKeyHere"
BASE_URL="https://api.firmhound.com"

# Search buyout firms
curl -s "${BASE_URL}/v1/gps?strategy=buyout&min_aum=1000000000&limit=5" \
  -H "Authorization: Bearer ${API_KEY}" \
  | jq '.data[] | {name: .legal_name, aum: .total_aum}'

# Get specific GP details
curl -s "${BASE_URL}/v1/gps/123456" \
  -H "Authorization: Bearer ${API_KEY}" \
  | jq '.data'

# Get GP's funds
curl -s "${BASE_URL}/v1/gps/123456/funds" \
  -H "Authorization: Bearer ${API_KEY}" \
  | jq '.data[] | {name: .name, vintage: .vintage_year, gav: .gross_asset_value}'

# Unified search
curl -s "${BASE_URL}/v1/search?q=apollo&types=gp,fund&limit=5" \
  -H "Authorization: Bearer ${API_KEY}" \
  | jq '.'

Error Responses

All errors return JSON with the following structure:

json
{
  "detail": "Error message describing what went wrong"
}

Common Status Codes

CodeMeaningCommon Causes
200OKRequest succeeded
400Bad RequestInvalid parameters, missing required fields
401UnauthorizedMissing or invalid API key
403ForbiddenValid key but insufficient permissions
404Not FoundResource (GP/fund) doesn't exist
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer-side error (rare)
503Service UnavailableDatabase unreachable, maintenance

Error Examples

401 Unauthorized - Invalid API Key:

json
{
  "detail": "Invalid or revoked API key"
}

429 Too Many Requests - Rate Limit Exceeded:

json
{
  "detail": "Rate limit exceeded. Limit: 100/day. Resets at: 2025-12-12T00:00:00Z"
}

400 Bad Request - Invalid Parameters:

json
{
  "detail": "Invalid strategy: 'invalid'. Valid strategies: buyout, venture, real-estate, ..."
}

404 Not Found:

json
{
  "detail": "Fund manager with CRD 999999 not found"
}

Rate Limiting

How It Works

  • Rate limits are enforced per API key
  • Limits reset daily at midnight UTC
  • Current usage is tracked in response headers
  • Exceeded limits return 429 Too Many Requests

Response Headers

Every API response includes rate limit headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 85
X-RateLimit-Reset: 2025-12-12T00:00:00Z

Handling Rate Limits

Python Example:

python
import time

def make_request_with_retry(client, func, *args, **kwargs):
    """Make API request with automatic retry on rate limit."""
    while True:
        try:
            return func(*args, **kwargs)
        except requests.HTTPError as e:
            if e.response.status_code == 429:
                reset_time = e.response.headers.get('X-RateLimit-Reset')
                print(f"Rate limit hit. Resets at {reset_time}")
                time.sleep(60)  # Wait 1 minute and retry
            else:
                raise

Best Practices:

  • Monitor X-RateLimit-Remaining header
  • Implement exponential backoff for retries
  • Cache results when possible
  • Upgrade tier if hitting limits regularly

Pagination

All list endpoints support pagination using limit and offset parameters.

Example:

bash
# Get first page (results 0-19)
curl "${BASE_URL}/v1/gps?limit=20&offset=0" \
  -H "Authorization: Bearer ${API_KEY}"

# Get second page (results 20-39)
curl "${BASE_URL}/v1/gps?limit=20&offset=20" \
  -H "Authorization: Bearer ${API_KEY}"

Response includes pagination metadata:

json
{
  "data": [...],
  "meta": {
    "total": 156,
    "limit": 20,
    "offset": 0
  }
}

Calculate pages:

python
total_results = response['meta']['total']
limit = response['meta']['limit']
total_pages = (total_results + limit - 1) // limit

Best Practices

Security

DO:

  • Store API keys in environment variables or secrets manager
  • Use HTTPS for all requests (enforced)
  • Rotate keys regularly (every 90 days recommended)
  • Monitor last_used_at timestamp for suspicious activity
  • Create separate keys for different applications

DON'T:

  • Commit keys to version control
  • Share keys publicly or in client-side code
  • Log full API keys (log only last 4 characters)
  • Use the same key across development/production

Performance

DO:

  • Use specific filters to reduce result sets
  • Implement client-side caching for reference data
  • Use autocomplete endpoint for typeahead UI
  • Request only needed fields when available
  • Batch requests when possible

DON'T:

  • Fetch all results without pagination
  • Poll endpoints excessively (use webhooks when available)
  • Make redundant requests for static data

Error Handling

python
import requests

def safe_api_call(url, headers):
    try:
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()
        return response.json()
    except requests.Timeout:
        print("Request timed out")
    except requests.HTTPError as e:
        if e.response.status_code == 429:
            print("Rate limit exceeded")
        elif e.response.status_code == 401:
            print("Invalid API key")
        else:
            print(f"HTTP error: {e}")
    except requests.RequestException as e:
        print(f"Request failed: {e}")

API Changelog

v1.1.0 (Current - December 2025)

New Endpoints:

  • GET /v1/gps/{crd}/regulatory - SEC enforcement & BrokerCheck data ($0.50/request)
  • GET /v1/gps/{crd}/amendments - ADV filing history ($0.25/request)
  • GET /v1/gps/{crd}/changes - Field change tracking ($0.25/request)
  • GET /v1/gps/{crd}/metrics - Derived analytics (AUM growth, fund cadence) ($0.15/request)
  • GET /v1/gps/{crd}/related - Similar GP recommendations ($0.15/request)
  • GET /v1/funds/{fund_id}/amendments - Fund amendment history ($0.25/request)
  • GET /v1/search/aggregate - Market-level aggregations ($0.15/request)

Enhancements:

  • Per-record billing infrastructure (FS-6030)
  • Volume discounts for high-usage customers
  • 24-hour caching for regulatory data

v1.0.0 (November 2025)

Initial Release:

  • GP search with 15+ filters
  • Fund search with vintage/GAV filtering
  • Unified search across GPs and funds
  • Autocomplete for typeahead UI
  • API key authentication
  • Rate limiting by tier
  • Reference data endpoints (strategies, locations)

Coming Soon:

  • Saved searches with alerts
  • Watchlist functionality
  • CSV export (Pro tier)
  • Webhooks for data updates
  • Time-series analytics

Support


Additional Resources

  • API Key Management Guide: /docs/API_KEY_MANAGEMENT.md
  • API Key Quickstart: /docs/API_KEY_QUICKSTART.md
  • Deployment Checklist: /docs/API_KEY_DEPLOYMENT_CHECKLIST.md

Last Updated: 2025-12-12 API Version: 1.1.0

Firmhound API Documentation