Surfe Company Search API
Searches for companies against Ideal Customer Profile (ICP) filters such as industry, employee count, revenue, location, and keywords, returning matching organizations with domains and firmographic metadata.
Searches for companies against Ideal Customer Profile (ICP) filters such as industry, employee count, revenue, location, and keywords, returning matching organizations with domains and firmographic metadata.
openapi: 3.0.3
info:
title: Surfe API
version: '2.0'
description: >-
The Surfe API (formerly Leadjet) provides B2B people and company search plus
enrichment. It returns verified professional emails and mobile phone numbers,
company firmographics, and lookalike account recommendations. Bulk enrichment
is asynchronous: start a job with POST and either poll the GET job endpoint or
receive a webhook callback. All requests are authenticated with a Bearer API
key managed from the Surfe dashboard.
contact:
name: Surfe API Support
url: https://developers.surfe.com/
x-former-name: Leadjet
servers:
- url: https://api.surfe.com/v2
description: Surfe API v2 production base URL
security:
- bearerAuth: []
tags:
- name: People
description: Search and enrich individual contacts.
- name: Companies
description: Search and enrich organizations.
- name: Recommendations
description: ICP definition and lookalike account recommendations.
- name: Account
description: Credit balance and account utilities.
paths:
/people/search:
post:
tags:
- People
summary: Search people
description: >-
Search for people by persona filters (job titles, seniorities,
departments) and company filters (industry, headcount, location).
Job titles are expanded automatically with acronym and semantic matching.
Results are paged with nextPageToken.
operationId: searchPeople
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PeopleSearchRequest'
responses:
'200':
description: Matching people.
content:
application/json:
schema:
$ref: '#/components/schemas/PeopleSearchResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/InsufficientCredits'
'429':
$ref: '#/components/responses/RateLimited'
/people/enrich:
post:
tags:
- People
summary: Enrich people (start)
description: >-
Start an asynchronous bulk enrichment job for up to 10,000 people. Each
person is identified by a LinkedIn URL, or by first name + last name +
company name or domain. Returns an enrichment ID for polling or a webhook
callback.
operationId: startPeopleEnrichment
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PeopleEnrichmentRequest'
responses:
'202':
description: Enrichment job accepted.
content:
application/json:
schema:
$ref: '#/components/schemas/EnrichmentJobAccepted'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/InsufficientCredits'
'429':
$ref: '#/components/responses/RateLimited'
/people/enrich/{id}:
get:
tags:
- People
summary: Enrich people (get)
description: >-
Retrieve the status and results of a people enrichment job by ID. Poll
until status is COMPLETED, or use a webhook to be notified.
operationId: getPeopleEnrichment
parameters:
- name: id
in: path
required: true
description: The enrichment job ID returned by the start operation.
schema:
type: string
format: uuid
responses:
'200':
description: Enrichment job status and enriched people.
content:
application/json:
schema:
$ref: '#/components/schemas/PeopleEnrichmentResult'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimited'
/people/find-by-email:
post:
tags:
- People
summary: Find people by email
description: >-
Enrich people directly from a list of email addresses, returning the
matched person profile and firmographics where available.
operationId: findPeopleByEmail
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- emails
properties:
emails:
type: array
items:
type: string
format: email
description: Email addresses to enrich.
responses:
'200':
description: Matched people.
content:
application/json:
schema:
type: object
properties:
people:
type: array
items:
$ref: '#/components/schemas/EnrichedPerson'
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/RateLimited'
/companies/search:
post:
tags:
- Companies
summary: Search companies
description: >-
Search for companies against Ideal Customer Profile filters (industry,
employee count, revenue, location, keywords). When credit charging is
enabled the call deducts ICP search credits and returns 402 when the
balance is insufficient.
operationId: searchCompanies
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CompanySearchRequest'
responses:
'200':
description: Matching companies.
content:
application/json:
schema:
$ref: '#/components/schemas/CompanySearchResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/InsufficientCredits'
'429':
$ref: '#/components/responses/RateLimited'
/companies/enrich:
post:
tags:
- Companies
summary: Enrich companies (start)
description: >-
Start an asynchronous bulk enrichment job for companies identified by
domain. Returns an enrichment ID for polling or a webhook callback.
operationId: startCompanyEnrichment
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CompanyEnrichmentRequest'
responses:
'202':
description: Enrichment job accepted.
content:
application/json:
schema:
$ref: '#/components/schemas/EnrichmentJobAccepted'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/InsufficientCredits'
'429':
$ref: '#/components/responses/RateLimited'
/companies/enrich/{id}:
get:
tags:
- Companies
summary: Enrich companies (get)
description: >-
Retrieve the status and results of a company enrichment job by ID. Poll
until status is COMPLETED, or use a webhook to be notified.
operationId: getCompanyEnrichment
parameters:
- name: id
in: path
required: true
description: The enrichment job ID returned by the start operation.
schema:
type: string
format: uuid
responses:
'200':
description: Enrichment job status and enriched companies.
content:
application/json:
schema:
$ref: '#/components/schemas/CompanyEnrichmentResult'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimited'
/recommendations/icp:
post:
tags:
- Recommendations
summary: Create or update ICP
description: >-
Create or update the Ideal Customer Profile used to generate lookalike
account recommendations.
operationId: upsertICP
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ICPDefinition'
responses:
'200':
description: ICP saved.
content:
application/json:
schema:
$ref: '#/components/schemas/ICPDefinition'
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/RateLimited'
/recommendations/fetch:
post:
tags:
- Recommendations
summary: Fetch lookalike recommendations
description: >-
Fetch lookalike account recommendations resembling the best-fit
companies defined by the ICP.
operationId: fetchRecommendations
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
limit:
type: integer
minimum: 1
maximum: 200
description: Maximum number of recommendations to return.
pageToken:
type: string
description: Pagination token from a previous response.
responses:
'200':
description: Lookalike company recommendations.
content:
application/json:
schema:
type: object
properties:
companies:
type: array
items:
$ref: '#/components/schemas/Company'
nextPageToken:
type: string
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/RateLimited'
/credits:
get:
tags:
- Account
summary: Get credit balance
description: >-
Return the remaining credit balance across the email, mobile, and
search/ICP credit pools.
operationId: getCredits
responses:
'200':
description: Current credit balances.
content:
application/json:
schema:
$ref: '#/components/schemas/CreditBalance'
'401':
$ref: '#/components/responses/Unauthorized'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: >-
Surfe API key issued from the Surfe dashboard, sent as
`Authorization: Bearer {api-key}`.
responses:
Unauthorized:
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: Resource or job not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
InsufficientCredits:
description: Not enough credits to complete the request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
RateLimited:
description: >-
Too many requests. The API allows up to 10 requests per second with
short bursts to 20, plus a daily request quota.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
schemas:
Error:
type: object
properties:
message:
type: string
code:
type: string
PeopleFilters:
type: object
description: Person-based filters.
properties:
jobTitles:
type: array
items:
type: string
description: >-
Job titles to match. Titles are expanded automatically with
bidirectional acronym and semantic matching.
seniorities:
type: array
items:
type: string
departments:
type: array
items:
type: string
countries:
type: array
items:
type: string
CompanyFilters:
type: object
description: Company-based filters.
properties:
industries:
type: array
items:
type: string
employeeCount:
$ref: '#/components/schemas/Range'
revenue:
$ref: '#/components/schemas/Range'
countries:
type: array
items:
type: string
domains:
type: array
items:
type: string
keywords:
type: array
items:
type: string
Range:
type: object
properties:
from:
type: integer
to:
type: integer
PeopleSearchRequest:
type: object
required:
- limit
properties:
limit:
type: integer
minimum: 1
maximum: 200
description: Maximum results per page.
people:
$ref: '#/components/schemas/PeopleFilters'
companies:
$ref: '#/components/schemas/CompanyFilters'
peoplePerCompany:
type: integer
minimum: 1
maximum: 5
description: Maximum results returned per company.
pageToken:
type: string
description: Pagination token from a previous response.
PeopleSearchResponse:
type: object
properties:
people:
type: array
items:
$ref: '#/components/schemas/Person'
total:
type: integer
nextPageToken:
type: string
Person:
type: object
properties:
firstName:
type: string
lastName:
type: string
jobTitle:
type: string
seniorities:
type: array
items:
type: string
departments:
type: array
items:
type: string
companyName:
type: string
companyDomain:
type: string
country:
type: string
linkedInUrl:
type: string
externalID:
type: string
PeopleEnrichmentRequest:
type: object
required:
- people
- include
properties:
people:
type: array
minItems: 1
maxItems: 10000
description: >-
People to enrich. Each entry needs at least a linkedinUrl, or
firstName + lastName + companyName or companyDomain.
items:
$ref: '#/components/schemas/PersonInput'
include:
type: object
description: Which fields to retrieve.
properties:
email:
type: boolean
mobile:
type: boolean
linkedInUrl:
type: boolean
jobHistory:
type: boolean
enrichmentOptions:
type: object
properties:
acceptedEmailType:
type: string
enum:
- professional
- personal
skipMobileEnrichmentIfNoEmailFound:
type: boolean
notificationOptions:
type: object
properties:
webhookUrl:
type: string
format: uri
PersonInput:
type: object
properties:
linkedinUrl:
type: string
firstName:
type: string
lastName:
type: string
companyName:
type: string
companyDomain:
type: string
externalID:
type: string
EnrichmentJobAccepted:
type: object
properties:
enrichmentID:
type: string
format: uuid
enrichmentCallbackURL:
type: string
format: uri
message:
type: string
description: Estimated completion time.
PeopleEnrichmentResult:
type: object
properties:
enrichmentID:
type: string
format: uuid
status:
$ref: '#/components/schemas/JobStatus'
percentCompleted:
type: integer
people:
type: array
items:
$ref: '#/components/schemas/EnrichedPerson'
EnrichedPerson:
allOf:
- $ref: '#/components/schemas/Person'
- type: object
properties:
emails:
type: array
items:
$ref: '#/components/schemas/EmailRecord'
mobilePhones:
type: array
items:
$ref: '#/components/schemas/PhoneRecord'
jobHistory:
type: array
items:
$ref: '#/components/schemas/JobHistoryEntry'
status:
type: string
EmailRecord:
type: object
properties:
email:
type: string
format: email
type:
type: string
enum:
- professional
- personal
validationStatus:
type: string
PhoneRecord:
type: object
properties:
mobilePhone:
type: string
confidenceScore:
type: number
JobHistoryEntry:
type: object
properties:
companyName:
type: string
companyDomain:
type: string
jobTitle:
type: string
startDate:
type: string
endDate:
type: string
CompanySearchRequest:
type: object
required:
- filters
- limit
properties:
limit:
type: integer
minimum: 1
maximum: 200
filters:
$ref: '#/components/schemas/CompanyFilters'
pageToken:
type: string
CompanySearchResponse:
type: object
properties:
companies:
type: array
items:
$ref: '#/components/schemas/Company'
total:
type: integer
nextPageToken:
type: string
CompanyEnrichmentRequest:
type: object
required:
- companies
properties:
companies:
type: array
minItems: 1
description: Companies to enrich, identified by domain and/or externalID.
items:
type: object
properties:
domain:
type: string
externalID:
type: string
include:
type: object
properties:
firmographics:
type: boolean
phoneNumbers:
type: boolean
notificationOptions:
type: object
properties:
webhookUrl:
type: string
format: uri
CompanyEnrichmentResult:
type: object
properties:
enrichmentID:
type: string
format: uuid
status:
$ref: '#/components/schemas/JobStatus'
percentCompleted:
type: integer
companies:
type: array
items:
$ref: '#/components/schemas/Company'
Company:
type: object
properties:
name:
type: string
domain:
type: string
websites:
type: array
items:
type: string
description:
type: string
industry:
type: string
keywords:
type: array
items:
type: string
employeeCount:
type: integer
revenue:
type: string
founded:
type: integer
hqCountry:
type: string
hqAddress:
type: string
linkedInUrl:
type: string
linkedInFollowersCount:
type: integer
phones:
type: array
items:
type: string
isPublic:
type: boolean
stockExchange:
type: string
stockSymbol:
type: string
fundingRounds:
type: array
items:
type: object
properties:
type:
type: string
amount:
type: number
date:
type: string
parentOrganization:
type: string
externalID:
type: string
status:
type: string
ICPDefinition:
type: object
properties:
name:
type: string
filters:
$ref: '#/components/schemas/CompanyFilters'
CreditBalance:
type: object
properties:
emailCredits:
type: integer
mobileCredits:
type: integer
searchCredits:
type: integer
JobStatus:
type: string
enum:
- PENDING
- IN_PROGRESS
- COMPLETED
- FAILED