Mastering B2B Data Enrichment APIs: Full Coding Tutorial

Sales teams generate inbound leads every day, but these leads often lack crucial information. For example, as a sales rep you might focus solely on Financial Services clients, but without industry data you’re left sorting through irrelevant prospects. No good! Or maybe you’ve crafted the perfect pitch for enterprise clients, but without knowing a company’s revenue, you can’t personalise your approach with confidence. Fret no more! Surfe’s Data Enrichment API has the answer you’ve been searching for (if your question was how do I enrich my contact list seamlessly).
Surfe’s enrichment API takes a basic prospecting list and enriches it with key company details such as Industry, Company Name and Revenue. With this data at your fingertips, you can:
Filter leads by industry to focus on the right prospects.
Prioritize high-value accounts by company size.
Personalize outreach for better engagement.
Speed up lead qualification and improve routing.
In this post, we’ll walk through the API code that makes it happen and show you how to integrate it into your sales process with a simple bit of code.
- Prerequisites
- Step 1: Setting Up Your Environment
- Step 2: Preparing Your Contact Data
- Step 3: Building the Enrichment Script
- Step 4: Running the Script
- Final Notes: Credits, Quotas, and Rate Limiting
By the end of this tutorial, you’ll have a fully functioning Python script that:
- Reads a CSV file of contacts
- Extracts key information
- Sends bulk enrichment requests to Surfe’s API
- Retrieves enriched detailed company data
- Outputs a new, enriched CSV ready to use in your sales process
Let’s get started and put the power of automated enrichment to work for you!
Prerequisites
1. Python 3.x installed
Most modern operating systems come with Python 3 pre-installed. To check if Python is installed on your system:
- Windows: Open Command Prompt (Win + R, type cmd, press Enter) and run:
py --version
- macOS/Linux: Open Terminal and run:
python3 --version
- If Python is not installed, download it from the official Python website (or beginner guide to downloads) and follow the installation instructions for your OS.
2. Basic Python knowledge
3. Surfe account and API key
To use Surfe’s API, you’ll need to create an account and obtain an API key. You can find the API documentation and instructions for generating your API key here: Surfe Developer Docs.
Step 1: Setting Up Your Environment
1.1 Creating a Virtual Environment (Optional but Recommended)
To keep your dependencies organized, you can create a virtual environment:
env # macOS/Linux
source env/bin/activate
py -m venv env # Windows
env\Scripts\activate #
1.2 Installing Required Packages
Ensure you have the following packages installed:
python3 -m pip install requests pandas python-dotenv # macOS/Linux
py -m pip install requests pandas python-dotenv #Windows
-
requests
(for API calls)
-
pandas
(for CSV data handling)
-
python-dotenv
(for storing API keys securely)
1.3 Setting Up Your API Key Securely
It’s best to avoid hardcoding API keys in your script. Instead, store them in environment variables:
- Create a .env file in your project root:
SURFE_API_KEY=YOUR_API_KEY
- Create your python script file enrich_contacts.py, Add all package imports, And load the key in your Python script:
import pandas as pd
import requests
import time
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.environ['SURFE_API_KEY']
Step 2: Preparing Your Contact Data
Before making API calls, you need a properly formatted CSV file. In this example, we’ll use a placeholder CSV file to demonstrate the process. However in most use cases you will typically be working with files uploaded via a CSV uploader or fetched directly from a cloud storage bucket. It should follow the following requirements.
2.1 CSV File Format Requirements
Your CSV file should contain the following columns:
- First Name
- Last Name
- Email Address
- Job Title
The Surfe API for contact enrichment requires specific field combinations in the people array for successful enrichment. You must provide one of the following:
- A LinkedIn URL
(linkedinUrl)
- A combination of First Name, Last Name, and Company Name
- A combination of First Name, Last Name, and Company Website
In this example we will be extracting company domain from the email field in our CSV file, we’ll use First Name, Last Name, and Company Website. This will allow the API to accurately identify and enrich company details for each contact.
2.2 Sample Data Structure
Example contacts.csv:
2.3 Data Validation Checks
Before processing, ensure:
- No missing or duplicate entries
- Email addresses follow a valid format
- Data is properly structured
Step 3: Building the Enrichment Script
Part 1: Reading and Processing Input Data
We will use pandas to read the CSV file and extract the required fields. This is how we will initially read the csv into our script.
contacts_df = pd.read_csv('contacts.csv')
Then we will start extracting the company domains from the Email Address field in our input CSV, and create an array of unique organizations
unique_domains = list(set(contacts_df['Email Address'].apply(lambda x: x.split('@')[-1])))
organizations = [{'domain': domain} for domain in unique_domains]
Part 2: Making API Requests
2.1 Setting Up API Authentication
#The api_key is the variable we defined in step 1.3
headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
2.2 Creating the Request Payload
company_request_body = {
'name': 'Enriched Companies',
'organizations': organizations
}
2.3 Sending the API Request
company_enrich_url = 'https://api.surfe.com/v1/organizations/enrichments/bulk'
company_response = requests.post(company_enrich_url, headers=headers, json=company_request_body)
2.4 Handling API Errors
You can refer to the API Docs for a detailed responses & errors explanation. But in this specific case we would be looking for a success code 202, and the enrichment process ID which we will later use to poll the response.
if company_response.status_code != 202: print(f"Error: Company enrichment request failed with status code {company_response.status_code}") print("Response:", company_response.json()) exit(1) company_enrichment_id = company_response.json().get('id') if not company_enrichment_id: print("Error: 'id' not found in company enrichment response") exit(1)
Part 3: Processing API Responses
The enrichment API works in two steps: first, you submit an enrichment request, and Surfe returns a unique request ID. Then, using this request ID, you wait for Surfe to gather the contact details and retrieve the results once they are ready.
In this example we keep the logic fairly simple, checking if the request is completed before waiting 0.5 seconds to try again.
Polling for Results
company_results_url = f'https://api.surfe.com/v1/organizations/enrichments/bulk/{company_enrichment_id}'
while True:
company_results_response = requests.get(company_results_url, headers=headers)
company_results_data = company_results_response.json()
if company_results_data.get('status') != 'IN_PROGRESS':
break
time.sleep(0.5)
After the request is completed we will map the enriched company data, and combine them with the original contacts to prepare them for the output CSV:
enriched_companies = {}
for org in company_results_data.get('organizations', []):
domain = org.get('website')
if domain:
industries = org.get('industries', [])
industry = industries[0].get('industry') if industries else 'N/A'
enriched_companies[domain] = {
'company_name': org.get('name'),
'company_industry': industry,
'company_revenue': org.get('annualRevenueRange')
}
# Combine enriched data with original contacts
enriched_contacts = []
for index, row in contacts_df.iterrows():
email_domain = row['Email Address'].split('@')[-1]
company_info = enriched_companies.get(email_domain, {})
enriched_contact = {
'First Name': row['First Name'],
'Last Name': row['Last Name'],
'Email Address': row['Email Address'],
'Job Title': row.get('Job Title'),
'Company Name': company_info.get('company_name'),
'Company Industry': company_info.get('company_industry'),
'Company Revenue': company_info.get('company_revenue')
}
enriched_contacts.append(enriched_contact)
Last step is writing the newly found data into a different output csv file:
enriched_contacts_df = pd.DataFrame(enriched_contacts)
enriched_contacts_df = enriched_contacts_df.fillna('N/A')
enriched_contacts_df.to_csv('enriched_contacts.csv', index=False)
Step 4: Running the Script
4.1 Executing the Python Script
To run the script, navigate to the directory where your script is saved and execute:
python3 enrich_contacts.py
4.2 Verifying Output
- Ensure that enriched_contacts.csv is generated in your working directory.
- Open the CSV file and confirm that company details have been successfully appended.
Output CSV
Final Notes: Credits, Quotas, and Rate Limiting
Credits & Quotas
Surfe’s API uses a credit system for people enrichment. Retrieving email, landline, and job details consumes email credits, while retrieving mobile phone numbers consumes mobile credits. There are also daily quotas, such as 2,000 people enrichments per day and 200 organization look-alike searches per day. For more information on credits and quotas, please speak to a Surfe representative to discuss a tailored plan that works for you and your business needs. Quotas reset at midnight (local time), and additional credits can be purchased if needed. For full details, refer to the Credits & Quotas documentation.
Rate Limiting
Surfe enforces rate limits to ensure fair API usage. Users can make up to 10 requests per second, with short bursts of up to 20 requests allowed. The limit resets every minute. Exceeding this results in a 429 Too Many Requests error, so it’s recommended to implement retries in case of rate limit issues. Learn more in the Rate Limits documentation.

Ready to take it a step further?
Click the button, you know you want to…
Data Enrichment API FAQs
What Is a Data Enrichment API?
A data enrichment API enhances your existing data by pulling in additional, relevant details from external sources. This means no more outdated or incomplete contact lists – just accurate, up-to-date information about your prospects. By integrating with your CRM or sales tools, a data enrichment API keeps your records up-to-date – which in turn helps you personalize outreach and improve conversion rates.
How Does a Data Enrichment API Improve Sales Prospecting?
A data enrichment API improves sales prospecting processes by automating data collection, reducing manual research, and improving targeting. Instead of spending hours trawling Google or searching LinkedIn for data, reps get instant access to verified contact details, job titles, and company insights. This makes outreach more personalized and effective, increasing response rates and shortening sales cycles. Plus, enriched data helps teams qualify leads more accurately, so they can focus on high-potential prospects instead of wasting time on poor-fit ones.
Can a Data Enrichment API Help Shorten Sales Cycles?
Absolutely! With complete and accurate prospect data, outreach is more precise from the start. A data enrichment API provides real-time updates, making sure reps always have the latest contact details and technographic and firmographic insights. This leads to more meaningful conversations earlier in the sales process, speeding up decision-making and reducing the back-and-forth.
What Types of Data Can a Data Enrichment API Provide?
A data enrichment API pulls in a wide range of data points, including:
- Company insights (industry, revenue, employee count, location)
- Firmographic data (company structure, funding, growth indicators)
- Technographic data (tech stack, software usage)
- Verified contact details (emails, phone numbers, job titles)
With this information, sales teams can craft hyper-targeted outreach strategies, making sure they connect with the right people at the right companies. Plus, because the data is always up-to-date, there’s no risk of relying on outdated information that could kill a deal before it even starts.
How Do You Integrate a Data Enrichment API Into Your Sales Workflow?
Integrating a data enrichment API is simple – most solutions, like Surfe’s, plug right into your existing sales stack. Whether you use a CRM, LinkedIn, an outbound automation tool, or all of the above, a good API will fit right into your workflow. Once connected, it automatically updates and enriches contact and company data, reducing manual research. Many APIs also allow for custom workflows, meaning you can set up specific triggers for enrichment, prioritize high-value leads, and automate prospecting.