Prospeo search API skill

This skill should be used when searching for people/leads using the Prospeo Search Person API.

by growthenginenowoslawski·MIT license·★ 736 Stars on the repo·GitHub ↗

Use now

Files of Prospeo search API

growthenginenowoslawski/main1 file shown
SKILL.md
Show the full text332 lines

Prospeo Search Person API

This skill documents how to use the Prospeo Search Person API for finding leads with filters.

When to Use

Use this skill when:

  • Searching for people/leads by job title, industry, location, company size, etc.
  • Building lead lists from Prospeo's database
  • Running large US-wide searches that need state-by-state crawling

API Overview

Endpoint: POST https://api.prospeo.io/search-person

Authentication: X-KEY header with API key

Rate Limits:

  • 2-2.5 requests/second (120-150 req/min)
  • Token bucket implementation recommended

Result Limits:

  • 25 results per page
  • 1000 pages max = 25,000 results per search
  • 1 credit per search request that returns at least 1 result

Request Format

POST /search-person
Headers: {
  'Content-Type': 'application/json',
  'X-KEY': process.env.PROSPEO_API_KEY
}
Body: {
  page: number,        // 1-1000
  filters: ProspeoSearchFilters
}

Filter Types

interface ProspeoSearchFilters {
  // Location (use "State, United States #US" format)
  person_location_search?: {
    include?: string[];  // e.g., ["California, United States #US"]
    exclude?: string[];
  };

  // Job titles
  person_job_title?: {
    include?: string[];  // e.g., ["CEO", "Founder"]
    exclude?: string[];
    match_only_exact_job_titles?: boolean;
  };

  // Company size
  company_headcount_custom?: {
    min?: number;  // e.g., 11
    max?: number;  // e.g., 500
  };

  // Industry
  company_industry?: {
    include?: string[];  // e.g., ["Information Technology"]
    exclude?: string[];
  };

  // Technology stack
  company_technology?: {
    include?: string[];  // e.g., ["Salesforce", "HubSpot"]
    exclude?: string[];
  };

  // Contact requirements
  person_contact_details?: {
    email?: string[];   // ["VERIFIED"] for verified emails only
    mobile?: string[];
    operator?: string;
  };

  // Duplicate control
  person_duplicate_control?: {
    hide_people_from_all_my_lists?: boolean;
    hide_people_already_exported_before?: boolean;
  };

  // Funding (use this for "recently raised Series X" targeting)
  company_funding?: {
    // Days since last funding round. Valid values: 90, 180, 270, 365, or null (None).
    // Maps to UI dropdown "Select last funding round date".
    funding_date?: 90 | 180 | 270 | 365 | null;

    // Last funding round amount (bucketed enum range).
    // Valid bucket values: "<100K", "100K-500K", "500K-1M", "1M-5M", "5M-10M",
    // "10M-25M", "25M-50M", "50M-100M", "100M-500M", "500M+", "Max"
    last_funding?: { min?: string; max?: string } | null;

    // Total funding raised across all rounds (same bucketed enum range as last_funding).
    total_funding?: { min?: string; max?: string };

    // Funding stage checkboxes. Valid values:
    //   "Pre seed", "Seed", "Series unknown", "Series A", "Series B",
    //   "Series C", "Series D", "Series E-J",
    //   "Grant", "Angel", "Private equity", "Debt financing",
    //   "Non equity assistance", "Post IPO equity", "Undisclosed",
    //   "Post IPO debt", "Product crowdfunding", "Equity crowdfunding",
    //   "Corporate round", "Convertible note", "Secondary market",
    //   "Initial coin offering", "Post IPO secondary"
    stage?: string[];
  };

  // Company filters
  company_name?: { include?: string[]; exclude?: string[] };
  company_domain?: { include?: string[]; exclude?: string[] };
  company_revenue_custom?: { min?: number; max?: number };
  company_founding_year?: { min?: number; max?: number };
}

Response Format

interface ProspeoSearchApiResponse {
  error: boolean;
  message?: string;
  results?: ProspeoSearchResult[];
  pagination?: {
    current_page: number;
    total_page: number;
    total_count: number;
    per_page: number;  // Always 25
  };
}

interface ProspeoSearchResult {
  person: {
    person_id: string;
    first_name?: string;
    last_name?: string;
    full_name?: string;
    current_job_title?: string;
    linkedin_url?: string;
    email?: string;
    email_status?: string;
    phone?: string;
    location?: {
      city?: string;
      state?: string;
      country?: string;
    };
    job_history?: Array<{
      title?: string;
      company_name?: string;
      current?: boolean;
    }>;
  };
  company?: {
    company_id?: string;
    name?: string;
    domain?: string;
    linkedin_url?: string;
    industry?: string;
    headcount?: number;
    headcount_range?: string;
    technologies?: string[];
    location?: { city?: string; state?: string; country?: string };
  };
}

State-by-State Crawling Pattern

For US-wide searches exceeding 25K results, split by state:

const US_STATES_BY_SIZE = [
  'California', 'Texas', 'Florida', 'New York', 'Illinois', 'Pennsylvania',
  'Ohio', 'Georgia', 'North Carolina', 'Michigan', 'New Jersey', 'Virginia',
  'Washington', 'Arizona', 'Massachusetts', 'Tennessee', 'Indiana', 'Missouri',
  'Maryland', 'Wisconsin', 'Colorado', 'Minnesota', 'South Carolina', 'Alabama',
  'Louisiana', 'Kentucky', 'Oregon', 'Oklahoma', 'Connecticut', 'Utah', 'Iowa',
  'Nevada', 'Arkansas', 'Mississippi', 'Kansas', 'New Mexico', 'Nebraska',
  'Idaho', 'West Virginia', 'Hawaii', 'New Hampshire', 'Maine', 'Montana',
  'Rhode Island', 'Delaware', 'South Dakota', 'North Dakota', 'Alaska',
  'Vermont', 'Wyoming'
];

// Format for location filter
function formatStateLocation(state: string): string {
  return `${state}, United States #US`;
}

// Replace "United States #US" with state-specific location
function createStateFilters(baseFilters, state) {
  const stateFilters = JSON.parse(JSON.stringify(baseFilters));
  stateFilters.person_location_search.include =
    stateFilters.person_location_search.include.map(loc =>
      loc === 'United States #US' ? formatStateLocation(state) : loc
    );
  return stateFilters;
}

Rate Limiting Implementation

// Token bucket rate limiter
class TokenBucket {
  private tokens: number;
  private lastRefill: number;
  private maxTokens = 5;
  private refillRate = 2.0; // tokens per second

  async acquire(): Promise<void> {
    this.refill();
    if (this.tokens >= 1) {
      this.tokens -= 1;
      return;
    }
    const waitMs = Math.ceil(((1 - this.tokens) / this.refillRate) * 1000);
    await this.sleep(Math.max(waitMs, 500));
    this.refill();
    this.tokens -= 1;
  }
}

Error Handling

// Retry on 429 with exponential backoff
if (status === 429 && retryCount < 5) {
  const backoffMs = Math.min(2000 * Math.pow(2, retryCount), 60000);
  await sleep(backoffMs);
  return searchPeople(filters, page, retryCount + 1);
}

Example: Search for Tech Executives

const filters: ProspeoSearchFilters = {
  person_location_search: {
    include: ['United States #US']
  },
  person_job_title: {
    include: ['CEO', 'CTO', 'VP Engineering', 'Head of Engineering'],
    match_only_exact_job_titles: false
  },
  company_headcount_custom: {
    min: 11,
    max: 500
  },
  company_industry: {
    include: ['Information Technology', 'Software']
  },
  person_contact_details: {
    email: ['VERIFIED']
  }
};

const service = new ProspeoSearchService();
const { results, summary } = await service.searchWithStateSplitting(filters, {
  maxTotalContacts: 10000,
  maxContactsPerState: 5000
});

Example: Recently Raised Series A

Target marketing leaders at US software companies (50–200 employees) that raised Series A in the last 180 days:

const filters: ProspeoSearchFilters = {
  person_location_search: { include: ['United States #US'] },
  person_job_title: {
    include: [
      'CMO', 'Chief Marketing Officer',
      'VP Marketing', 'Vice President Marketing',
      'Head Marketing', 'Director Marketing',
      'Growth', 'VP Growth', 'Head Growth'
    ]
  },
  company_headcount_custom: { min: 50, max: 200 },
  company_industry: {
    include: ['Software Development', 'Computer Software', 'Information Technology & Services']
  },
  company_funding: {
    funding_date: 180,
    stage: ['Series A']
  },
  person_contact_details: { email: ['VERIFIED'] }
};

Set funding_date to 90 / 180 / 270 / 365 for tighter or looser recency windows. Use null (or omit) to ignore recency and match any company currently at the given stage.

Existing Implementation

The codebase has a full implementation at:

  • Service: Desktop/Cursor Testing/src/services/prospeoSearch.ts
  • Types: Desktop/Cursor Testing/src/types/prospeoSearch.ts
  • CLI: Desktop/Cursor Testing/src/scripts/prospeoSearch.ts

Environment Variables

PROSPEO_API_KEY=your_api_key_here

What to do next

This is a reference skill — no direct next step. Used by /prospeo-full-export and /auto-research-public to build the actual search.

Return to the skill that sent you here.

  • /prospeo-full-export — the main consumer of this reference
  • /auto-research-public — also uses Prospeo search via phase-prospeo.ts
1---
2name: prospeo-search-api
3description: This skill should be used when searching for people/leads using the Prospeo Search Person API. It provides the correct API format, filter types, rate limiting patterns, and state-by-state crawling techniques to overcome the 25K result limit. Use when building lead lists, searching by job title/industry/location, or integrating with Prospeo.
4---
5 
6# Prospeo Search Person API
7 
8This skill documents how to use the Prospeo Search Person API for finding leads with filters.
9 
10## When to Use
11 
12Use this skill when:
13- Searching for people/leads by job title, industry, location, company size, etc.
14- Building lead lists from Prospeo's database
15- Running large US-wide searches that need state-by-state crawling
16 
17## API Overview
18 
19**Endpoint:** `POST https://api.prospeo.io/search-person`
20 
21**Authentication:** `X-KEY` header with API key
22 
23**Rate Limits:**
24- 2-2.5 requests/second (120-150 req/min)
25- Token bucket implementation recommended
26 
27**Result Limits:**
28- 25 results per page
29- 1000 pages max = 25,000 results per search
30- 1 credit per search request that returns at least 1 result
31 
32## Request Format
33 
34```typescript
35POST /search-person
36Headers: {
37 'Content-Type': 'application/json',
38 'X-KEY': process.env.PROSPEO_API_KEY
39}
40Body: {
41 page: number, // 1-1000
42 filters: ProspeoSearchFilters
43}
44```
45 
46## Filter Types
47 
48```typescript
49interface ProspeoSearchFilters {
50 // Location (use "State, United States #US" format)
51 person_location_search?: {
52 include?: string[]; // e.g., ["California, United States #US"]
53 exclude?: string[];
54 };
55 
56 // Job titles
57 person_job_title?: {
58 include?: string[]; // e.g., ["CEO", "Founder"]
59 exclude?: string[];
60 match_only_exact_job_titles?: boolean;
61 };
62 
63 // Company size
64 company_headcount_custom?: {
65 min?: number; // e.g., 11
66 max?: number; // e.g., 500
67 };
68 
69 // Industry
70 company_industry?: {
71 include?: string[]; // e.g., ["Information Technology"]
72 exclude?: string[];
73 };
74 
75 // Technology stack
76 company_technology?: {
77 include?: string[]; // e.g., ["Salesforce", "HubSpot"]
78 exclude?: string[];
79 };
80 
81 // Contact requirements
82 person_contact_details?: {
83 email?: string[]; // ["VERIFIED"] for verified emails only
84 mobile?: string[];
85 operator?: string;
86 };
87 
88 // Duplicate control
89 person_duplicate_control?: {
90 hide_people_from_all_my_lists?: boolean;
91 hide_people_already_exported_before?: boolean;
92 };
93 
94 // Funding (use this for "recently raised Series X" targeting)
95 company_funding?: {
96 // Days since last funding round. Valid values: 90, 180, 270, 365, or null (None).
97 // Maps to UI dropdown "Select last funding round date".
98 funding_date?: 90 | 180 | 270 | 365 | null;
99 
100 // Last funding round amount (bucketed enum range).
101 // Valid bucket values: "<100K", "100K-500K", "500K-1M", "1M-5M", "5M-10M",
102 // "10M-25M", "25M-50M", "50M-100M", "100M-500M", "500M+", "Max"
103 last_funding?: { min?: string; max?: string } | null;
104 
105 // Total funding raised across all rounds (same bucketed enum range as last_funding).
106 total_funding?: { min?: string; max?: string };
107 
108 // Funding stage checkboxes. Valid values:
109 // "Pre seed", "Seed", "Series unknown", "Series A", "Series B",
110 // "Series C", "Series D", "Series E-J",
111 // "Grant", "Angel", "Private equity", "Debt financing",
112 // "Non equity assistance", "Post IPO equity", "Undisclosed",
113 // "Post IPO debt", "Product crowdfunding", "Equity crowdfunding",
114 // "Corporate round", "Convertible note", "Secondary market",
115 // "Initial coin offering", "Post IPO secondary"
116 stage?: string[];
117 };
118 
119 // Company filters
120 company_name?: { include?: string[]; exclude?: string[] };
121 company_domain?: { include?: string[]; exclude?: string[] };
122 company_revenue_custom?: { min?: number; max?: number };
123 company_founding_year?: { min?: number; max?: number };
124}
125```
126 
127## Response Format
128 
129```typescript
130interface ProspeoSearchApiResponse {
131 error: boolean;
132 message?: string;
133 results?: ProspeoSearchResult[];
134 pagination?: {
135 current_page: number;
136 total_page: number;
137 total_count: number;
138 per_page: number; // Always 25
139 };
140}
141 
142interface ProspeoSearchResult {
143 person: {
144 person_id: string;
145 first_name?: string;
146 last_name?: string;
147 full_name?: string;
148 current_job_title?: string;
149 linkedin_url?: string;
150 email?: string;
151 email_status?: string;
152 phone?: string;
153 location?: {
154 city?: string;
155 state?: string;
156 country?: string;
157 };
158 job_history?: Array<{
159 title?: string;
160 company_name?: string;
161 current?: boolean;
162 }>;
163 };
164 company?: {
165 company_id?: string;
166 name?: string;
167 domain?: string;
168 linkedin_url?: string;
169 industry?: string;
170 headcount?: number;
171 headcount_range?: string;
172 technologies?: string[];
173 location?: { city?: string; state?: string; country?: string };
174 };
175}
176```
177 
178## State-by-State Crawling Pattern
179 
180For US-wide searches exceeding 25K results, split by state:
181 
182```typescript
183const US_STATES_BY_SIZE = [
184 'California', 'Texas', 'Florida', 'New York', 'Illinois', 'Pennsylvania',
185 'Ohio', 'Georgia', 'North Carolina', 'Michigan', 'New Jersey', 'Virginia',
186 'Washington', 'Arizona', 'Massachusetts', 'Tennessee', 'Indiana', 'Missouri',
187 'Maryland', 'Wisconsin', 'Colorado', 'Minnesota', 'South Carolina', 'Alabama',
188 'Louisiana', 'Kentucky', 'Oregon', 'Oklahoma', 'Connecticut', 'Utah', 'Iowa',
189 'Nevada', 'Arkansas', 'Mississippi', 'Kansas', 'New Mexico', 'Nebraska',
190 'Idaho', 'West Virginia', 'Hawaii', 'New Hampshire', 'Maine', 'Montana',
191 'Rhode Island', 'Delaware', 'South Dakota', 'North Dakota', 'Alaska',
192 'Vermont', 'Wyoming'
193];
194 
195// Format for location filter
196function formatStateLocation(state: string): string {
197 return `${state}, United States #US`;
198}
199 
200// Replace "United States #US" with state-specific location
201function createStateFilters(baseFilters, state) {
202 const stateFilters = JSON.parse(JSON.stringify(baseFilters));
203 stateFilters.person_location_search.include =
204 stateFilters.person_location_search.include.map(loc =>
205 loc === 'United States #US' ? formatStateLocation(state) : loc
206 );
207 return stateFilters;
208}
209```
210 
211## Rate Limiting Implementation
212 
213```typescript
214// Token bucket rate limiter
215class TokenBucket {
216 private tokens: number;
217 private lastRefill: number;
218 private maxTokens = 5;
219 private refillRate = 2.0; // tokens per second
220 
221 async acquire(): Promise<void> {
222 this.refill();
223 if (this.tokens >= 1) {
224 this.tokens -= 1;
225 return;
226 }
227 const waitMs = Math.ceil(((1 - this.tokens) / this.refillRate) * 1000);
228 await this.sleep(Math.max(waitMs, 500));
229 this.refill();
230 this.tokens -= 1;
231 }
232}
233```
234 
235## Error Handling
236 
237```typescript
238// Retry on 429 with exponential backoff
239if (status === 429 && retryCount < 5) {
240 const backoffMs = Math.min(2000 * Math.pow(2, retryCount), 60000);
241 await sleep(backoffMs);
242 return searchPeople(filters, page, retryCount + 1);
243}
244```
245 
246## Example: Search for Tech Executives
247 
248```typescript
249const filters: ProspeoSearchFilters = {
250 person_location_search: {
251 include: ['United States #US']
252 },
253 person_job_title: {
254 include: ['CEO', 'CTO', 'VP Engineering', 'Head of Engineering'],
255 match_only_exact_job_titles: false
256 },
257 company_headcount_custom: {
258 min: 11,
259 max: 500
260 },
261 company_industry: {
262 include: ['Information Technology', 'Software']
263 },
264 person_contact_details: {
265 email: ['VERIFIED']
266 }
267};
268 
269const service = new ProspeoSearchService();
270const { results, summary } = await service.searchWithStateSplitting(filters, {
271 maxTotalContacts: 10000,
272 maxContactsPerState: 5000
273});
274```
275 
276## Example: Recently Raised Series A
277 
278Target marketing leaders at US software companies (50–200 employees) that raised
279Series A in the last 180 days:
280 
281```typescript
282const filters: ProspeoSearchFilters = {
283 person_location_search: { include: ['United States #US'] },
284 person_job_title: {
285 include: [
286 'CMO', 'Chief Marketing Officer',
287 'VP Marketing', 'Vice President Marketing',
288 'Head Marketing', 'Director Marketing',
289 'Growth', 'VP Growth', 'Head Growth'
290 ]
291 },
292 company_headcount_custom: { min: 50, max: 200 },
293 company_industry: {
294 include: ['Software Development', 'Computer Software', 'Information Technology & Services']
295 },
296 company_funding: {
297 funding_date: 180,
298 stage: ['Series A']
299 },
300 person_contact_details: { email: ['VERIFIED'] }
301};
302```
303 
304Set `funding_date` to `90` / `180` / `270` / `365` for tighter or looser recency windows.
305Use `null` (or omit) to ignore recency and match any company currently at the given stage.
306 
307## Existing Implementation
308 
309The codebase has a full implementation at:
310- Service: `Desktop/Cursor Testing/src/services/prospeoSearch.ts`
311- Types: `Desktop/Cursor Testing/src/types/prospeoSearch.ts`
312- CLI: `Desktop/Cursor Testing/src/scripts/prospeoSearch.ts`
313 
314## Environment Variables
315 
316```bash
317PROSPEO_API_KEY=your_api_key_here
318```
319 
320---
321 
322## What to do next
323 
324This is a reference skill — no direct next step. Used by `/prospeo-full-export` and `/auto-research-public` to build the actual search.
325 
326Return to the skill that sent you here.
327 
328## Related skills
329 
330- `/prospeo-full-export` — the main consumer of this reference
331- `/auto-research-public` — also uses Prospeo search via phase-prospeo.ts
332 

Discussion

Alternatives

API and interface designGuides stable API and interface design. Use when designing APIs, module boundaries, or any public interface. Use when creating REST or GraphQL endpoints, defining type contracts between modules, or establishing boundaries between frontend and backend.Coding · MITContext7Pulls up-to-date, version-specific library docs and code examples into the prompt so the AI stops inventing old APIs.Coding · MITContext7 Documentation LookupFetch up-to-date documentation and code examples for any library, framework, SDK, CLI tool, or cloud service. Use whenever the user asks about a specific library — even well-known ones like React, Next.js, Prisma, Express, Tailwind, Django, or Spring Boot — because training data may not reflect recent API changes or version updates. Always use for: API syntax questions, configuration options, version migration issues, "how do I" questions mentioning a library name, debugging that involves library-specific behavior, setup instructions, and CLI tool usage. Use even when you think you know the answer. Do not rely on training data for API details, signatures, or configuration options — they are frequently out of date. Prefer this over web search for library documentation.Coding · MITAdaptyv Bio Foundry APIHow to use the Adaptyv Bio Foundry API and Python SDK for protein experiment design, submission, and results retrieval. Use this skill whenever the user mentions Adaptyv, Foundry API, protein binding assays, protein screening experiments, BLI/SPR assays, thermostability assays, or wants to submit protein sequences for experimental characterization. Also trigger when code imports `adaptyv`, `adaptyv_sdk`, or `FoundryClient`, or references `foundry-api-public.adaptyvbio.com`.Science · MIT