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:
# 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:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"user": {
"id": 123,
"email": "you@example.com",
"tier": "starter"
}
}2. Create an API Key
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:
{
"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
curl "https://api.firmhound.com/v1/gps?strategy=buyout&limit=5" \
-H "Authorization: Bearer fh_live_AbCd1234EfGh5678IjKl9012MnOp3456QrSt7890UvWxYz"Response:
{
"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_AbCd1234EfGh5678IjKl9012MnOp3456QrSt7890UvWxYzAPI Key Format
- Prefix:
fh_live_(production) orfh_test_(development) - Length: 52 characters
- Encoding: Base58 (alphanumeric, no ambiguous characters)
Rate Limits by Tier
| Tier | Requests/Day | Best For |
|---|---|---|
| Starter | 100 | Testing, small projects |
| Growth | 10,000 | Production apps |
| Scale | Unlimited | Enterprise use |
Rate limit headers (returned with each response):
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 2025-12-12T00:00:00ZSession Management
Manage active login sessions across devices.
GET /v1/auth/sessions
List all active sessions for the authenticated user.
Request:
curl "https://api.firmhound.com/v1/auth/sessions" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"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:
curl -X DELETE "https://api.firmhound.com/v1/auth/sessions/sess_xyz789ghi012" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"message": "Session terminated successfully",
"session_id": "sess_xyz789ghi012"
}DELETE /v1/auth/sessions
Sign out all other devices (terminate all sessions except current).
Request:
curl -X DELETE "https://api.firmhound.com/v1/auth/sessions" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"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:
curl -X POST "https://api.firmhound.com/v1/auth/verify-email" \
-H "Content-Type: application/json" \
-d '{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}'Response (200 OK):
{
"message": "Email verified successfully",
"email": "you@example.com",
"verified_at": "2025-12-12T15:30:00Z"
}Error Response (400 Bad Request - Invalid/Expired Token):
{
"detail": "Invalid or expired verification token"
}Error Response (409 Conflict - Already Verified):
{
"detail": "Email already verified"
}POST /v1/auth/resend-verification
Resend verification email to user's email address.
Request:
curl -X POST "https://api.firmhound.com/v1/auth/resend-verification" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"message": "Verification email sent",
"email": "you@example.com",
"sent_at": "2025-12-12T15:35:00Z"
}Error Response (409 Conflict - Already Verified):
{
"detail": "Email already verified"
}Error Response (429 Too Many Requests - Rate Limited):
{
"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:
curl "https://api.firmhound.com/v1/auth/me" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response:
{
"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:
| Scenario | subscription_plan | api_tier | App Access | API Access |
|---|---|---|---|---|
| App-only user | pro | starter | Full Pro features | 100 req/day |
| API-only user | free | growth | Basic app access | 10,000 req/day |
| Full access | enterprise | scale | All app features | Unlimited API |
Upgrading Tiers
- App subscription: Upgrade via
app.firmhound.com/settings/billing - API tier: Upgrade via
developers.firmhound.com/billingor 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:
curl "https://api.firmhound.com/health"Response (200 OK):
{
"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):
{
"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:
curl "https://api.firmhound.com/v1/stats"Response:
{
"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:
| Parameter | Type | Description | Example |
|---|---|---|---|
q | string | Search query (name, location) | blackstone |
strategy | string | Primary strategy | buyout, venture, real-estate |
min_aum | integer | Minimum AUM (USD) | 1000000000 (1B) |
max_aum | integer | Maximum AUM (USD) | 10000000000 (10B) |
state | string | US state code | NY, CA, TX |
country | string | Country | United States, United Kingdom |
min_employees | integer | Minimum employee count | 50 |
max_employees | integer | Maximum employee count | 500 |
has_funds | boolean | Only GPs with funds | true |
limit | integer | Results per page (1-100) | 20 |
offset | integer | Pagination offset | 0 |
sort | string | Sort field | aum, name, employees |
order | string | Sort order | desc, asc |
Request:
curl "https://api.firmhound.com/v1/gps?strategy=buyout&min_aum=1000000000&state=NY&limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"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:
curl "https://api.firmhound.com/v1/gps/123456" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"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):
{
"detail": "Fund manager with CRD 123456 not found"
}GET /v1/gps/{crd}/funds
Get all funds managed by a specific GP.
Request:
curl "https://api.firmhound.com/v1/gps/123456/funds" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"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:
curl "https://api.firmhound.com/v1/gps/123456/stats" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"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=trueto bypass
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
event_type | string | all | Filter: disciplinary, regulatory, civil, all |
after_date | date | - | Only events after this date (YYYY-MM-DD) |
force_refresh | boolean | false | Bypass cache and fetch fresh from BrokerCheck |
Request:
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:
{
"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 actionsregulatory: SEC, FINRA, state regulator actionscivil: Civil court proceedingscriminal: Criminal proceedings (rare)
GET /v1/gps/{crd}/amendments
Get ADV filing amendment history for a GP.
Pricing: $0.25/request (flat fee)
Query Parameters:
| Parameter | Type | Default | Max | Description |
|---|---|---|---|---|
limit | integer | 50 | 100 | Max amendments to return |
Request:
curl "https://api.firmhound.com/v1/gps/123456/amendments?limit=25" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"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 cyclewithdrawal: 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:
| Parameter | Type | Default | Max | Description |
|---|---|---|---|---|
limit | integer | 50 | 100 | Max change records to return |
Request:
curl "https://api.firmhound.com/v1/gps/123456/changes" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"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:
curl "https://api.firmhound.com/v1/gps/123456/metrics" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"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 growthaum_growth.cagr_3y_percent: 3-year compound annual growth ratefund_launch_cadence_months: Average months between fund launchesavg_fund_size_trend_percent: Recent funds vs earlier funds size comparison
GET /v1/gps/{crd}/related
Find similar GPs based on configurable similarity factors.
Pricing: $0.15/request (flat fee)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
similarity_factors | string | strategy,aum_band,geography | Comma-separated factors |
limit | integer | 10 | Max 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:
curl "https://api.firmhound.com/v1/gps/123456/related?similarity_factors=strategy,geography&limit=5" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"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:
| Parameter | Type | Default | Max | Description |
|---|---|---|---|---|
limit | integer | 50 | 100 | Number of team members to return |
role | string | all | - | Filter: partner, md, vp, associate, other |
sort | string | seniority | - | Sort by seniority (most senior first) |
Request Examples:
# 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:
{
"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 responsetotal_available: Total team members for this GPhas_more: Boolean indicating if more people exist beyond limitnext_page_cost: Estimated cost to retrieve next page (same limit)
Private Funds
GET /v1/funds
Search private funds with multiple filters.
Query Parameters:
| Parameter | Type | Description | Example |
|---|---|---|---|
q | string | Search fund name | opportunity |
strategy | string | Investment strategy | buyout, venture |
min_vintage | integer | Minimum vintage year | 2015 |
max_vintage | integer | Maximum vintage year | 2023 |
min_gav | integer | Minimum GAV (USD) | 100000000 |
max_gav | integer | Maximum GAV (USD) | 5000000000 |
is_3c1 | boolean | SEC Rule 3(c)(1) funds | true |
is_3c7 | boolean | SEC Rule 3(c)(7) funds | true |
limit | integer | Results per page (1-100) | 20 |
offset | integer | Pagination offset | 0 |
Request:
curl "https://api.firmhound.com/v1/funds?strategy=venture&min_vintage=2020&limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"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:
curl "https://api.firmhound.com/v1/funds/2001" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"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:
| Parameter | Type | Default | Max | Description |
|---|---|---|---|---|
limit | integer | 50 | 100 | Max amendments to return |
Request:
curl "https://api.firmhound.com/v1/funds/805-1234567890/amendments" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"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"
}
}
}Search
GET /v1/search
Unified search across both GPs and funds.
Query Parameters:
| Parameter | Type | Description | Example |
|---|---|---|---|
q | string (required) | Search query (min 2 chars) | blackstone |
types | string | Comma-separated types | gp,fund |
limit | integer | Results per type (1-20) | 5 |
Request:
curl "https://api.firmhound.com/v1/search?q=apollo&types=gp,fund&limit=5" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"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:
| Parameter | Type | Description | Example |
|---|---|---|---|
q | string (required) | Partial query (min 2 chars) | apol |
type | string | Filter by type | gp, fund, all |
limit | integer | Max suggestions (1-20) | 10 |
Request:
curl "https://api.firmhound.com/v1/search/autocomplete?q=apol&limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"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:
| Parameter | Type | Required | Description |
|---|---|---|---|
group_by | string | Yes | strategy, vintage, geography, aum_band |
country | string | No | Filter by country |
strategy | string | No | Filter by strategy |
min_aum | integer | No | Filter by minimum AUM |
min_vintage | integer | No | Filter by minimum vintage year |
max_vintage | integer | No | Filter by maximum vintage year |
Aggregation Types:
strategy: AUM and GP count by primary strategyvintage: Fund count and AUM by vintage yeargeography: GP count and AUM by state/countryaum_band: GP distribution by AUM bands (<100M, 100M-500M, 500M-1B, 1B-10B, >10B)
Request Examples:
# 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):
{
"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):
{
"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):
{
"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):
{
"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:
curl "https://api.firmhound.com/v1/strategies"Response:
{
"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:
curl "https://api.firmhound.com/v1/locations"Response:
{
"data": {
"states": [
{
"state": "NY",
"count": 4521
},
{
"state": "CA",
"count": 3876
}
],
"countries": [
{
"country": "United States",
"count": 18234
},
{
"country": "United Kingdom",
"count": 1987
}
]
}
}Code Examples
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
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
#!/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:
{
"detail": "Error message describing what went wrong"
}Common Status Codes
| Code | Meaning | Common Causes |
|---|---|---|
200 | OK | Request succeeded |
400 | Bad Request | Invalid parameters, missing required fields |
401 | Unauthorized | Missing or invalid API key |
403 | Forbidden | Valid key but insufficient permissions |
404 | Not Found | Resource (GP/fund) doesn't exist |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Server-side error (rare) |
503 | Service Unavailable | Database unreachable, maintenance |
Error Examples
401 Unauthorized - Invalid API Key:
{
"detail": "Invalid or revoked API key"
}429 Too Many Requests - Rate Limit Exceeded:
{
"detail": "Rate limit exceeded. Limit: 100/day. Resets at: 2025-12-12T00:00:00Z"
}400 Bad Request - Invalid Parameters:
{
"detail": "Invalid strategy: 'invalid'. Valid strategies: buyout, venture, real-estate, ..."
}404 Not Found:
{
"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:00ZHandling Rate Limits
Python Example:
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:
raiseBest Practices:
- Monitor
X-RateLimit-Remainingheader - 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:
# 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:
{
"data": [...],
"meta": {
"total": 156,
"limit": 20,
"offset": 0
}
}Calculate pages:
total_results = response['meta']['total']
limit = response['meta']['limit']
total_pages = (total_results + limit - 1) // limitBest 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_attimestamp 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
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
- API Status: https://status.firmhound.com
- Interactive Docs: https://api.firmhound.com/docs
- Email Support: support@firmhound.com
- Developer Portal: https://developers.firmhound.com
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