Skip Trace API — Phone, Email & Address Lookup avatar

Skip Trace API — Phone, Email & Address Lookup

Pricing

from $6.00 / 1,000 person with contact data

Go to Apify Store
Skip Trace API — Phone, Email & Address Lookup

Skip Trace API — Phone, Email & Address Lookup

Skip trace anyone in the US by name, phone, email or address — one lookup or a list of 1,000, a few seconds each, no browser. Phones with carrier and line type, emails, addresses and relatives, merged from several people-search databases into one row. Pay only for named people with contact data.

Pricing

from $6.00 / 1,000 person with contact data

Rating

0.0

(0)

Developer

Mu0i

Mu0i

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

2 days ago

Last modified

Share

What does Skip Trace API do?

Skip trace anyone in the US from one clue — a name, a phone number, an email or a street address — and get back where they live, how to reach them, and who they're connected to. Paste one search or a list of up to 1,000, or point it at a spreadsheet. Every lookup is checked against several independent people-search databases at once, and records for the same person are merged into one row, so one result carries everything those sources know between them. It talks to the data sources directly — no browser to launch — so a search takes a few seconds, a 1,000-row list finishes in about half an hour, and a run never dies mid-list.

You pay $7 per 1,000 results, and only for results you can act on: a named person with a phone, an email or a street address. Searches that find nobody, name-only rows and errors are free. On the free Apify plan each run tries 10 searches and returns up to 3 results, so you can see real data before you pay anything.

What you get for each person

📞 Phone numberswith line type (wireless / landline / VoIP), carrier, and first/last-seen dates
✉️ Email addressesdeduplicated across sources
⭐ Best phone & best emailbestPhone / bestEmail — the one number and email to try first, at the top of each row for CSV export
🏠 Current addressstreet, city, state, ZIP, county
🚩 Absentee-owner flagon an address search, absenteeOwner tells you whether the owner lives at the property or elsewhere
🗂️ Address historyprevious addresses with first/last-reported dates
👪 Relatives & associatesnames with ages, where known
🪪 Identityfull name, age, birth month/year, deceased flag
✅ CorroborationmatchBasis — how strongly the row is confirmed across independent sources

Why use this skip tracing tool?

  • Fast, and it finishes. No headless browser to launch or babysit: each search takes about 5 seconds; three run at once by default, so a list of 1,000 completes in roughly 35 minutes (about 12 with maxConcurrency: 10), in 128 MB of memory. Measured on a 12-search mixed list: 26 seconds end to end.
  • Never charged for an empty row. A row is billed only when it names a person and gives a phone, an email or a street address. A search returns at most maxResults people (default 1), so a list of 1,000 can never come back as 5,000 rows or bill more than 1,000 results.
  • One row, several sources. Most skip trace tools return what a single site knows. This one queries several at once and folds the matching records together, then unions their phones, emails, addresses and relatives. Fewer rows, more in each.
  • The right person first. Name a town or ZIP in a search and people there rank above richer records elsewhere; the living rank above the deceased; a name search never returns a different surname. Relatives are listed family first (same surname), not a 50-name network.
  • Merged carefully. Two records are merged only when they share a street address, or a birth year and a town (the same city or ZIP code). Same-name strangers stay separate, even in the same state. So do a father and son at the same address (Jr / Sr).
  • You can see how sure a row is. Every result says whether it was confirmed by independent sources (address or name+dob+state) or comes from just one (single-source), so you can prioritize your outreach.
  • Live data. Each run queries the sources at that moment, not an old cached export.
  • Built for lists. Up to 1,000 names, addresses, phones and emails in one run, mixed freely, typed in or read from a CSV or a shared sheet. Every output row records the search it came from and its status, so it joins straight back to your spreadsheet or CRM.
  • Stops where you say. The run ends cleanly at your spending limit, never goes over it, and a platform restart picks up where it left off without re-running or re-charging anything.

Who uses skip tracing?

  • Real estate investors & wholesalers: skip trace property owners, reach absentee owners and motivated sellers.
  • Debt recovery & collections: locate debtors who have moved or changed numbers.
  • Process servers & legal teams: find a current address before you serve.
  • Sales & lead enrichment: turn a name and city into a phone and email.
  • Due diligence & fraud checks: confirm that a person, phone or email belong together.
  • Reconnecting: find lost contacts, heirs, alumni and old tenants.

How to use Skip Trace API

  1. Click Try for free to open the Actor's input form.
  2. Add one or more searches to any of the four lists. Each line is one search, and you can mix all four types in one run. Or paste a Google Sheet or CSV link into csvUrl (see Input below).
  3. Optionally add | Full Name to an entry to keep only that person, or raise maxResults.
  4. Click Start. Results appear in the Output tab, ready to export as CSV, Excel, JSON or HTML. The Call list view has one phone and one email per person; To re-run lists the entries that need another look.

The four search types and the field each one goes in:

Search byFieldExample entry
NamenameMichael Johnson; Los Angeles, CA or Michael Johnson; 90001
Address (reverse address lookup)street_citystatezip350 5th Ave; New York, NY
Phone (reverse phone lookup)phone_number(212) 665-1000
Email (reverse email lookup)emailsomeone@gmail.com

Input

All fields are optional, and any mix of them works in one run. The Input tab has the same fields as a form.

Example list input

{
"name": ["Michael Johnson; Los Angeles, CA", "Jane Doe; 78701"],
"street_citystatezip": ["350 5th Ave; New York, NY"],
"phone_number": ["(212) 665-1000", "+1 312-555-0100"],
"email": ["someone@gmail.com"],
"maxResults": 1
}

Pick one specific person

End any entry with | Full Name to keep only that person. This is handy when an address or phone number returns a whole household and the person you want is not the first one listed:

{
"street_citystatezip": ["350 5th Ave; New York, NY | John Smith"],
"phone_number": ["(212) 665-1000 | Jane Doe"]
}

The whole list of people at that address or number is checked, not just the first few. A match is returned with nameMatch: true. If nobody there has that name, you get a free not_found row whose message says how many other people the search found. Set fallbackWhenNoMatch: true to get the first person found instead, flagged nameMatch: false, so you can still tell the two cases apart.

From a CSV or Google Sheet

Paste a Google Sheet link into csvUrl (share the sheet as Anyone with the link → Viewer; the tab in the link is the one read), or a link to a CSV file (Google Drive and Dropbox links work too). Each row is one search, so a list of 1,000 rows bills like 1,000 searches. Name your columns and they are mapped automatically:

name,street_citystatezip,phone_number,email
John Smith,350 5th Ave; New York NY,,
,1600 Pennsylvania Ave; Washington DC,,
,,(212) 665-1000,

For a property-owner list, put the property in street_citystatezip (or address) and the owner in name: the owner name pinpoints the right resident at that address. Common export headers are understood: separate City, State and Zip columns are joined onto the street; Owner Name, Owner First Name + Owner Last Name, Property Address, Situs City and similar; Last, First names; full state names; ZIPs that lost a leading zero; title rows above the header. A mailing-address column is ignored (it is where the owner gets mail, not the property). A single column with no header is searched line by line with the type detected automatically. Duplicate rows are searched once. Rows from the file carry csvRow, the line number in your sheet, so results join back exactly. The CSV adds to anything typed in the lists above and is limited to 2 MB. If the sheet can't be read, the run ends with a message saying exactly why (private sheet, wrong link, Excel file) and costs nothing.

Optional settings

  • maxResults: the most people per search, from 1 to 50 (default 1, the best-corroborated match). Raise it for common names without a location, or to see everyone at an address. Each extra named person with contact data is another billed result.
  • personFilter: a | Full Name filter that applies to every entry without one of its own.
  • fallbackWhenNoMatch: when a | Full Name filter matches nobody, return the first person found (nameMatch: false) instead of a not_found row. Off by default, so a miss never costs anything.
  • csvUrl: a CSV or spreadsheet link to read searches from (see above).
  • flatOutput: also add the spreadsheet column layout other skip trace Actors use (Phone-1 … Phone-5 with Type / Provider / First and Last Reported, Email-1 … Email-5, Lives in, Street Address, County Name, Previous Addresses, Relatives …) on top of the regular fields, so an existing sheet, Zapier zap or CRM mapping keeps working unchanged. Off by default.
  • maxConcurrency: how many searches run at once, from 1 to 10 (default 3).

Up to 1,000 searches per run. Split bigger lists across runs, or schedule them. For long lists, raise the run timeout in Run options. If a run gets close to it, the Actor finishes cleanly and marks the remaining entries skipped, so you lose nothing and can re-run just those.

Tips for better matches

  • Add a city and state or a ZIP code to a name search (Jane Doe; Austin, TX). Common names without a location return many different people. In a big city, a ZIP (Michael Johnson; 90011) beats the city name: neighborhoods often carry their own postal city (Venice, Van Nuys, Hollywood), so a city-only search can rank a person listed under one of those below a name-only match downtown.
  • A person who lives in the town you named always ranks above a same-name person elsewhere, even a richer record. If nobody there has contact data, the top row is a free name-only row rather than a billed stranger from another state.
  • For an address search, put a ; between the street and the city/state/ZIP.
  • Phone numbers work in any format: 2126651000, (212) 665-1000 and +1 212-665-1000 are all fine.

Output

Every row starts with the search it answers (input, searchType) and a status:

statusMeaningCharged?
foundOne row per person foundOnly if it has a name plus a phone, an email or a street address
not_foundThe search found nobody, or nobody with the | Full Name you asked for (message says how many others it found)Free
invalid_inputThe entry can't be searched (e.g. a phone that isn't 10 digits); message says whyFree
errorA temporary failure; re-run this entryFree
skippedNot run: the spending limit, free-plan cap or run timeout was reached, or the first 100 searches found nobody (see FAQ)Free

Example result

{
"input": "Michael Johnson; Los Angeles, CA",
"searchType": "name",
"status": "found",
"matchBasis": "address",
"fullName": "Michael A Johnson",
"firstName": "Michael",
"middleName": "A",
"lastName": "Johnson",
"age": 47,
"birthYear": 1979,
"currentAddress": {
"street": "1234 W Example St",
"locality": "Los Angeles",
"region": "CA",
"postal": "90001",
"county": "Los Angeles",
"lastReported": "2026-08-01"
},
"bestPhone": "(213) 555-0142",
"bestEmail": "mjohnson@example.com",
"phones": [
{ "number": "(213) 555-0142", "type": "wireless", "carrier": "T-Mobile", "lastReported": "2026-07-15" },
{ "number": "(323) 555-0198", "type": "landline", "carrier": "AT&T" }
],
"emails": ["mjohnson@example.com"],
"previousAddresses": [
{ "street": "88 Sample Ave", "locality": "Pasadena", "region": "CA", "postal": "91101" }
],
"relatives": [{ "name": "Laura Johnson", "age": 45 }],
"associates": [{ "name": "David Kim", "age": 50 }]
}

The example is illustrative and the contact details are fictional.

bestPhone and bestEmail are the one number and email to try first (the most recent wireless line), at the top of every found row so a CSV export is callable without opening the nested phones array. On an address search, found rows also carry absenteeOwner: true when the person's current address is not the property you searched (an absentee owner — the direct-mail target), false when they live there. It is omitted when the two addresses can't be compared confidently.

Export as CSV or Excel and filter on status and input to match results back to your list. Filter on skipped or error to get exactly the entries to re-run, or on absenteeOwner to pull just the absentee owners.

How much does skip tracing cost?

$7.00 per 1,000 results ($0.007 per result), pay-per-event, with no subscription. Higher Apify plans get a lower rate.

You getYou pay
100 named people with a phone, email or street address$0.70
1,000 results$7.00
A search that finds nobody$0
A name-only row (no phone, email or address)$0
A row with a name and only a city, state or ZIP$0
A phone or email that comes back with no person behind it$0
A list of 1,000 searches at the default maxResults: 1at most $7.00
The same list with maxResults: 3at most $21.00

Set a maximum cost per run in Apify and the Actor will never go over it. It delivers the results it can bill, then marks the remaining searches skipped.

A run can never bill more than searches × maxResults. That ceiling is enforced in the Actor itself, independent of your cost limit. A run that is restarted by the platform picks up where it left off: finished searches are never re-run, re-delivered or re-charged.

You are not charged for Apify platform usage (compute, storage, data transfer): the price per result is all you pay, plus Apify's standard start event of $0.00005 per run.

Is skip tracing free to try?

Yes. On the free Apify plan each run tries up to 10 searches and returns up to 3 results, so you can see the data before you pay. Entries after that are marked skipped.

Need a volume, private or custom plan?

Email support@housedata.dev. We set up volume rates for steady list work, private deployments, custom input or output formats, and integrations (n8n, Make, your CRM). Say roughly how many searches a month and what the list looks like, and we'll answer within one business day.

Integrations and API

Use it from code, from no-code tools, or from an AI agent:

  • Apify API: run the Actor and fetch the results over REST. See the API tab for JavaScript, Python, cURL and OpenAPI examples.
  • Make, Zapier, n8n and spreadsheets: use Apify's integrations to start lookups from a new CRM lead or a spreadsheet row.
  • AI agents: add the Actor to Claude, Cursor or any agent that uses Apify's MCP integration. Every output field is documented in the dataset schema, so an agent knows what bestPhone or absenteeOwner means without guessing.
import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "<YOUR_APIFY_TOKEN>" });
const run = await client.actor("mu0i/skip-tracing-api").call({
phone_number: ["(212) 665-1000", "+1 312-555-0100"],
maxResults: 1,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("mu0i/skip-tracing-api").call(run_input={
"name": ["Jane Doe; Austin, TX", "Michael Johnson; 90001"],
"maxResults": 1,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
if row["status"] == "found":
print(row["input"], "→", row["fullName"], row.get("bestPhone"))

FAQ

Where does the skip tracing data come from?

From publicly available US records and people-search databases, queried live on each run. Coverage varies by person: someone with a long public footprint returns more than someone who has recently moved or keeps a low profile.

Can I paste the input from another skip trace Actor?

Usually as-is. The input field names (name, street_citystatezip, phone_number, email, plus max_results) and the | Full Name suffix work the same way. A misspelled field (street_citystatzip, adress) or a common alternative (addresses, phones) is read as the field you meant, and the run's status message says so. For the output, set flatOutput: true to get the same column names you have now (Search Option, Input Given, Lives in, Phone-1 … Phone-5, Email-1 … Email-5, Previous Addresses, Relatives), alongside ours.

How do I skip trace a list of property owners?

Export your list with the property address and the owner name, share it as a sheet (or a CSV link) and paste the link into csvUrl. The owner name pinpoints the right resident at each address, and every found row carries absenteeOwner, so filtering the export on absenteeOwner = true gives you the direct-mail list. See From a CSV or Google Sheet above for the column rules.

An address search returns the wrong resident

An address or phone search lists everyone linked to it, and with maxResults: 1 you get the best-corroborated one. To target a particular resident, add | First Last to the entry: 104 Main St; Marietta, GA 30067 | John Smith. Every person found for that address is checked, so it works even when the one you want is listed fifth or tenth. If nobody there matches, the row is a free not_found with a message; set fallbackWhenNoMatch: true if you'd rather get the first resident in that case.

The run stopped after 100 searches and marked the rest skipped

None of the first 100 searches found anyone. A real list almost always finds someone well before that, so this means the entries are not in a form the search understands: usually a wrong column, a name with no location, or an address without a ; before the city. Fix the format (see the examples above) and run again. Nothing was charged.

Check the field names first. The lists are name, street_citystatezip, phone_number and email. A field that can't be placed is reported as ignored rather than silently dropped. Addresses, phone numbers and emails pasted into the name list are recognised and searched as what they are. And since nothing is charged for a not_found, invalid_input or empty run, a wrong field name never costs you anything.

Can a run return or charge more rows than my list?

No. Each search returns at most maxResults people (default 1) plus its own status rows, which are free. The Actor refuses to bill past searches × maxResults in a run, finishes on its own when the list is done, and a restarted run never repeats a finished search. If you ever see more billed results than that, report the run and we'll refund the excess.

Why did I get fewer people than maxResults?

Records for the same person are merged, so several hits for one person become one row. That's intended: it means fewer duplicates and more data per row.

What does matchBasis mean?

  • address: independent sources agree on this person and share a street address. This is the strongest match.
  • name+dob+state: independent sources agree on name, birth year (within one year) and a town: the same city or ZIP code somewhere in the person's address history.
  • single-source: only one source returned this person.

Is a phone number guaranteed to be current?

No. Use lastReported and the line type to decide which number to try first. Wireless numbers with a recent date are usually the best bet, and that is what bestPhone picks.

Do you keep my searches or results?

Results are written only to your own Apify dataset.

What happens if a search fails?

Each search is retried automatically. If it still fails, that entry gets status: "error" and the rest of your list keeps going. Failed entries are never charged. A source outage is reported as error, never as not_found, so a "not found" really means nobody was found.

Something looks wrong, or I need a custom integration

Open an issue in the Issues tab with the input you used (leave out anything private), or email support@housedata.dev. Every issue gets an answer within one business day. For a custom workflow — a different input format, an n8n or Make template, a volume or private plan — email is best.

  • Coverage is US only.
  • Results are not a consumer report under the Fair Credit Reporting Act (FCRA). Do not use them for decisions about credit, employment, tenant screening, insurance, or any other FCRA purpose.
  • If you call or text people you find, you are responsible for complying with the TCPA, Do-Not-Call rules and state telemarketing laws.
  • Do not use this Actor to stalk, harass, threaten or discriminate against anyone, or for any unlawful purpose.
  • Data is provided as-is from public sources and may be incomplete or out of date. Verify it before you act on it.

More from the same team

Actors that pair well with skip tracing, by the same developer:

ActorWhat it gives youPairs with skip tracing for
Zillow Search ScraperListings by city or ZIP: price, status, days on market, zpidBuild the property list, then skip trace the owners here
Zillow Property ScraperThe full record for a property by zpidConfirm the property before you reach out
TikTok Search ScraperVideos, users and hashtags for any searchFind creators and local businesses to prospect
TikTok Places ScraperLocations and their reviewsLocal business lead lists
TikTok Video DownloaderMP4 / MP3 without a watermark—

All of them run on the same terms: pay per result, nothing for empty runs.