# People Skip Trace: Phone, Email & Address Lookup (`nice_dev/people-skip-trace-scraper`) Actor

Skip trace US people by name, address, phone or email: every phone number with line type and carrier, emails, age, past addresses, relatives, associates and property. CSV and CRM-friendly input, JSON/CSV/Excel export.

- **URL**: https://apify.com/nice\_dev/people-skip-trace-scraper.md
- **Developed by:** [Nice Dev](https://apify.com/nice_dev) (community)
- **Categories:** Lead generation, Real estate, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.13 / 1,000 people

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### 🔎 What is People Skip Trace?

**People Skip Trace** finds **US people** by **name, address, phone number or email** and returns their **phone numbers (mobile, landline or VoIP, with the carrier)**, **emails**, **age**, **current and past addresses**, **relatives and associates**, and the **property record of their home** — the data real-estate investors, wholesalers, collection agencies and CRMs use to reach an owner or a lead.

Paste a list of names, addresses, phone numbers or emails (or a CSV file), click **Start**, and download one row per person in JSON, CSV or Excel. It reads the free people-search sites FastPeopleSearch and CyberBackgroundChecks: **one person with a full report in about 40 seconds, about 13 people a minute** when a search returns many people.&#x20;

### 📋 What data can you extract with People Skip Trace?

One row per person, 81 fields:

| Category | What you get |
| --- | --- |
| 👤 **Person** | full name, first, middle and last name, other names used, age, month and year of birth, deceased or not and when |
| 🏠 **Current address** | street, city, state, ZIP code, county, living there since, map coordinates |
| 📞 **Phone numbers** | every number with its line type (mobile, landline, VoIP), carrier and date first reported, the main number first — the first 5 also in their own columns |
| ✉️ **Emails** | every email shown for the person — the first 5 also in their own columns; optionally checked with their email provider (valid, invalid, accept-all or unknown) |
| 🕰️ **Address history** | past addresses with their county and the month they were recorded |
| 👪 **Relatives and associates** | names, ages, month of birth and the page of each; possible spouse and marital status |
| 🏡 **Property of the home** | estimated value and equity, last sale amount and date, bedrooms, bathrooms, living and lot area, year built, owner-occupied or absentee owner |
| 💼 **Work and education** | employer and job title, schools and degrees, companies the person is linked to and the role held |
| 🔎 **Search and match** | the search it answers, your own id, the name looked for, whether the name matches and a match score |

Every field, with an example, is listed in the **Output** section below.

Phone numbers, emails, address history, ages of relatives, property, work and education come from the person's full report, sold apart: tick **Full person report** (off by default) to get them. Without it, each person comes with what the search result lists: name, age, city, relatives' names and past cities (plus the phone numbers an email search lists), never emails.

### ✅ Why use People Skip Trace?

- 📞 **Every phone number, typed**: mobile, landline or VoIP, carrier and date first reported — not just the first number.
- 🏡 **More than contacts**: the value, equity, last sale and occupancy of the person's home, their employer, schools and linked companies, their relatives and associates with ages.
- 🎯 **The right person first**: give the owner's name after an address (`| Janette Suarez`) and that person is returned first, even when they do not live there but are listed as a relative of the residents; first name and last name are both checked, nicknames tolerated.
- 📥 **Your lists as they are**: the same list format as the most used skip trace Actor of the Store, a list of objects for your CRM, or a CSV / Google Sheets link.
- 🔁 **Never pay twice**: tick **Only new people** and each later run skips the people already delivered.
- 🔌 API, scheduling, integrations (Make, Zapier, n8n, Google Sheets…) and JSON/CSV/Excel export via the Apify platform.

### 🚀 How to skip trace people

1. Create a free Apify account.
2. Open **People Skip Trace** and paste your searches into **Names**, **Addresses**, **Phone numbers** or **Emails** (one per line), or give a list of objects in **People (structured)**, or a **CSV file URL**.
3. Set **Max people** (100 by default, 0 = no limit) and **Max people per search** (1 by default = the best match of each search).
4. Tick **Full person report** for the phone numbers, emails and the rest of the report (off by default, charged per report).
5. Click **Start**.
6. Download the dataset in JSON, CSV, Excel or via API.

### 💰 How much does it cost to skip trace people?

This Actor uses **pay per event** pricing. Platform usage (compute, proxy) is included in the price.&#x20;

Price per 1,000, by Apify plan (Platinum and Diamond pay the Gold price):

| What you pay for | Free | Bronze | Silver | Gold |
| --- | --- | --- | --- | --- |
| 🔎 Each search run (`people-search`) — a name, an address, a phone or an email, **whether it finds someone or not** | $6.36 | $2.30 | $2.26 | **$2.23** |
| 👤 Each person saved | $6.09 | $2.20 | $2.17 | **$2.13** |
| 📞 Each full report read (`full-report`: phones, emails, address history, relatives, property — off by default) | $5.55 | $2.00 | $1.97 | **$1.94** |
| 📄 Each extra page of results (`results-page`: more people per search than a page holds, about 10) | $6.36 | $2.30 | $2.26 | **$2.23** |
| 🧹 Each person a filter drops before its report (`filter-check`) | $0.35 | $0.35 | $0.35 | $0.35 |
| 🧹 Each person a filter drops after reading its report (`detail-filter-check`, on top of the report) | $0.20 | $0.20 | $0.20 | $0.20 |
| ▶️ Each run start (`apify-actor-start`) | $0.0009 per GB of run memory ($0.0009 at the default 512 MB, $0.0018 at 2 GB, the most a run can take) | | | |

With the defaults (1 person per search, full report off), a search that finds its person costs **$4.36 per 1,000 on Gold** ($4.43 Silver, $4.5 Bronze, $12.45 Free), **$6.3 with the full report** ($6.4 Silver, $6.5 Bronze, $18 Free), and a search that finds nobody costs $2.23 per 1,000 on Gold. Example on Gold, with the full report: a list of 1,000 owners where 800 are found ≈ $5.49 (1,000 searches $2.23 + 800 people with their report $3.26 + $0.0009). Filtering never costs more than taking everything: a person you keep costs its normal price. With your own proxies (`proxyUrls`), searches, full reports and extra pages are not charged: you pay per person, per person a filter drops, and the run start only.

### ⚙️ Input

```json
{
    "name": ["Janette Suarez; Miami, FL"],
    "street_citystatezip": ["641 NW 59th Ave; Miami, FL 33126 | Janette Suarez"],
    "phone_number": ["(786) 523-6332"],
    "email": ["jane.doe@gmail.com"],
    "maxItems": 100
}
```

From a CRM or an automation, one object per search (your `id` comes back as `inputId`):

```json
{
    "people": [
        { "id": "crm-4812", "firstName": "Janette", "lastName": "Suarez", "street": "641 NW 59th Ave", "city": "Miami", "state": "FL", "zip": "33126" },
        { "id": "crm-4813", "phone": "7865236332" }
    ],
    "extractDetails": true,
    "requirePhone": true
}
```

From a spreadsheet, and only the people not delivered before:

```json
{
    "csvUrl": "https://docs.google.com/spreadsheets/d/1AbCdEfGhIjKlMnOpQrStUvWxYz/export?format=csv",
    "maxItemsPerQuery": 2,
    "onlyNew": true,
    "stateKey": "miami-owners"
}
```

| Field | Notes |
| --- | --- |
| `name` | One person per line, name then city and state: `Janette Suarez; Miami, FL`, or the state only: `Janette Suarez; FL`. A ZIP code may follow the state. Up to 1,000 lines per list. |
| `street_citystatezip` | One address per line: `641 NW 59th Ave; Miami, FL 33126`. Returns the people linked to the address, newest first. Add a vertical bar and a full name at the end of the line to put that person first (the owner, for example). |
| `phone_number` | Reverse phone lookup, one US number per line, any format: `(786) 523-6332`, `7865236332`, `+1 786 523 6332`. |
| `email` | Reverse email lookup, one email per line: `jane.doe@gmail.com`. |
| `people` | A JSON list of objects with any of `firstName`, `lastName`, `street`, `city`, `state`, `zip`, `phone`, `email` and your own `id` (returned as `inputId`): one search per object, by address when a street is given, else by phone, else by email, else by name. |
| `csvUrl` | Link to a CSV file with a header row (Google Sheets: `…/export?format=csv`, or the sheet's own link shared as "Anyone with the link"), max 5 MB. Recognised columns: `name` or `first name` and `last name`, `street` or `address`, `city`, `state`, `zip`, `phone`, `email`, `id`. |
| `startUrls` | FastPeopleSearch search pages or person pages (`https://www.fastpeoplesearch.com/juan-cortes_id_G-400600387843451335`), and CyberBackgroundChecks email pages. A person page IS the full report: it is read in full and charged as one, even with **Full person report** off. |
| `maxItems` | Stop after this many people for the whole run (`0` = unlimited). All lists, people, CSV rows and URLs together make up to 5,000 searches per run. |
| `maxItemsPerQuery` | People saved for EACH search: `1` = the best match only; raise it to get every resident of an address or every namesake; `0` = no per-search cap. |
| `extractDetails` | Full person report: every phone, email, past address, relatives and associates with ages, property, work (default off, charged per report). Off = what the search result lists, never emails. |
| `verifyEmails` | Check that emails exist (default off): each of the first 5 emails is checked with its email provider, no email is ever sent. Priced separately, only for a valid or invalid answer. Needs the full report (`extractDetails`): ignored when it is off. |
| `requireNameMatch` | With a name to look for, save only the people whose first and last names match it. |
| `requirePhone`, `requireEmail` | Only the people with at least one phone number, or one email. Both need the full report (`extractDetails`): they are ignored when it is off. |
| `minAge`, `maxAge` | Age range, for example `18` to `65`; people whose age is not known are kept. |
| `excludeKeywords` | Drop the people whose name contains one of these words: `LLC`, `Trust`. |
| `onlyNew`, `stateKey`, `resetState` | Monitoring: only the people never delivered under this memory key (`miami-owners`); `resetState` forgets the memory. |
| Advanced | `proxyConfiguration` (keep the default, included in the price; your own proxies are used when you give them; the residential proxy is not available), `maxConcurrency`, `maxRequestsPerMinute`, `minRequestIntervalMs`, `maxRequestRetries`, `debugLog`. |

### 📦 Output

One real row with **Full person report** on, shortened (lists cut to their first entries) and with the personal values masked (`X`). Without the report, the fields it fills stay empty (`null` or `[]`): the row keeps the name, age, city, state, relatives' names and past cities of the search result.

```json
{
    "id": "G189142XXXXXXXXXXXXX",
    "url": "https://www.fastpeoplesearch.com/janette-suarez_id_G189142XXXXXXXXXXXXX",
    "source": "fastpeoplesearch",
    "fullName": "Janette Suarez",
    "firstName": "Janette",
    "middleName": null,
    "lastName": "Suarez",
    "aliases": [
        "Janette S Garcia",
        "Janette R Garcia",
        "Janette Garcia"
    ],
    "age": 55,
    "born": "February 1971",
    "birthYear": 1971,
    "birthMonth": 2,
    "isDeceased": false,
    "deathDate": null,
    "currentAddress": "10XXX NW 19th Pl, Pembroke Pines, FL 33026",
    "street": "10XXX NW 19th Pl",
    "city": "Pembroke Pines",
    "state": "FL",
    "zip": "33026",
    "county": "Broward County",
    "livingSince": "December 2009",
    "currentAddressUrl": "https://www.fastpeoplesearch.com/address/10xxx-nw-19th-pl_pembroke-pines-fl-33026",
    "latitude": 26.03,
    "longitude": -80.29,
    "phones": [
        {
            "number": "(954) 589-XXXX",
            "e164": "+1954589XXXX",
            "type": "Wireless",
            "carrier": "New Cingular Wireless PCS LLC - GA",
            "firstReported": "July 2016",
            "isPrimary": true
        },
        {
            "number": "(954) 432-XXXX",
            "e164": "+1954432XXXX",
            "type": "Landline",
            "carrier": "Bellsouth Telecommunications Inc dba Southern Bell Telephone & Telegraph",
            "firstReported": "August 2010",
            "isPrimary": false
        }
    ],
    "phoneCount": 9,
    "bestPhone": "(954) 589-XXXX",
    "bestPhoneType": "Wireless",
    "bestPhoneCarrier": "New Cingular Wireless PCS LLC - GA",
    "phone1": "(954) 589-XXXX",
    "phone1Type": "Wireless",
    "phone1Carrier": "New Cingular Wireless PCS LLC - GA",
    "phone1FirstReported": "July 2016",
    "phone2": "(954) 432-XXXX",
    "phone2Type": "Landline",
    "phone2Carrier": "Bellsouth Telecommunications Inc dba Southern Bell Telephone & Telegraph",
    "phone2FirstReported": "August 2010",
    "phone3": "(305) 796-XXXX",
    "phone3Type": "Wireless",
    "phone3Carrier": "T-Mobile USA Inc",
    "phone3FirstReported": "March 2011",
    "phone4": "(954) 909-XXXX",
    "phone4Type": "Wireless",
    "phone4Carrier": "Omnipoint Miami E License LLC",
    "phone4FirstReported": "September 2020",
    "phone5": "(954) 251-XXXX",
    "phone5Type": "Voip",
    "phone5Carrier": "Comcast Phone of Florida LLC - FL",
    "phone5FirstReported": "September 2024",
    "emails": [
        "xxxxxxxx@hotmail.com"
    ],
    "emailCount": 1,
    "bestEmail": "xxxxxxxx@hotmail.com",
    "email1": "xxxxxxxx@hotmail.com",
    "email2": null,
    "email3": null,
    "email4": null,
    "email5": null,
    "emailChecks": [],
    "email1Status": null,
    "email2Status": null,
    "email3Status": null,
    "email4Status": null,
    "email5Status": null,
    "previousAddresses": [
        {
            "address": "29XX Bounty LN, Saint James City, FL 33956",
            "street": "29XX Bounty LN",
            "city": "Saint James City",
            "state": "FL",
            "zip": "33956",
            "county": "Lee County",
            "recorded": "June 2025"
        }
    ],
    "relatives": [
        {
            "name": "Rayvel G.",
            "age": 54,
            "born": "Nov 1971",
            "id": "G881691XXXXXXXXXXXXX",
            "url": "https://www.fastpeoplesearch.com/rayvel-g_id_G881691XXXXXXXXXXXXX"
        }
    ],
    "associates": [
        {
            "name": "Jose C.",
            "age": 79,
            "born": "Dec 1946",
            "id": "G365512XXXXXXXXXXXXX",
            "url": "https://www.fastpeoplesearch.com/jose-c_id_G365512XXXXXXXXXXXXX"
        }
    ],
    "possibleSpouse": {
        "name": "Rayvel Alain G.",
        "age": 54,
        "id": "G881691XXXXXXXXXXXXX",
        "url": "https://www.fastpeoplesearch.com/rayvel-alain-g_id_G881691XXXXXXXXXXXXX"
    },
    "maritalStatus": "Free public records suggest that Janette Suarez is likely married to Rayvel A. G.. Janette and Rayvel have lived together in at least 8 separate locations.",
    "property": {
        "bedrooms": 2,
        "bathrooms": 2,
        "squareFeet": 1450,
        "lotSquareFeet": 7200,
        "yearBuilt": 1974,
        "estimatedValue": 527000,
        "estimatedEquity": 338927,
        "lastSaleAmount": 139000,
        "lastSaleDate": "2009-11-30",
        "occupancyType": "Owner Occupied",
        "ownershipType": "Multiple",
        "landUse": "Single Family",
        "propertyClass": "Residential",
        "subdivision": "Pembroke Lakes Sec 1 76-40 B"
    },
    "isAbsentee": false,
    "employment": [],
    "education": [],
    "businesses": [],
    "searchType": "name",
    "searchInput": "Janette Suarez; Miami, FL",
    "inputId": null,
    "targetName": "Janette Suarez",
    "nameMatch": "matched",
    "matchScore": 95,
    "searchUrl": "https://www.fastpeoplesearch.com/name/janette-suarez_miami-fl",
    "scrapedAt": "2026-09-25T20:51:23.523Z"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV or Excel.

#### All 81 fields

| Fields | What you get |
| --- | --- |
| `id`, `url`, `source` | **Person**: the person's id and page on FastPeopleSearch, the site it was read on |
| `fullName`, `firstName`, `middleName`, `lastName`, `aliases` | `Janette Suarez`, `Janette`, `null`, `Suarez`, other names used |
| `age`, `born`, `birthYear`, `birthMonth` | `55`, `February 1971`, `1971`, `2` |
| `isDeceased`, `deathDate` | `true` when the site says the person passed away, and when (`October 2018`, the year only without the full report); `false` when it does not; empty when the site does not say (email search without the full report) |
| `currentAddress`, `street`, `city`, `state`, `zip`, `county` | **Current address**: one line, then its parts |
| `livingSince`, `currentAddressUrl`, `latitude`, `longitude` | month moved in (`December 2009`), the address page, map coordinates |
| `phones`, `phoneCount` | **Phone numbers**: every number with `number`, `e164`, `type`, `carrier`, `firstReported`, `isPrimary`; how many |
| `bestPhone`, `bestPhoneType`, `bestPhoneCarrier` | the main number, else the first mobile, else the first number |
| `phone1`, `phone1Type`, `phone1Carrier`, `phone1FirstReported` | first number in its own columns (`Wireless`, `New Cingular Wireless PCS LLC - GA`, `July 2016`) |
| `phone2`, `phone2Type`, `phone2Carrier`, `phone2FirstReported` | second number |
| `phone3`, `phone3Type`, `phone3Carrier`, `phone3FirstReported` | third number |
| `phone4`, `phone4Type`, `phone4Carrier`, `phone4FirstReported` | fourth number |
| `phone5`, `phone5Type`, `phone5Carrier`, `phone5FirstReported` | fifth number |
| `emails`, `emailCount`, `bestEmail` | **Emails**: every email, how many, the first one |
| `email1`, `email2`, `email3`, `email4`, `email5` | the first 5 emails in their own columns |
| `emailChecks` | **Check that emails exist** option (off by default): for each of the first 5 emails, `email`, `status`, `reason` (the answer in a few words, `mail server: 250 2.1.5 OK`), `checkedAt`; empty when the option is off |
| `email1Status`, `email2Status`, `email3Status`, `email4Status`, `email5Status` | the status of `email1`-`email5`: `valid` (the email provider confirms the mailbox exists: Gmail and the other providers that answer), `invalid` (the domain takes no email, or the provider says the mailbox does not exist), `accept-all` (the domain accepts any address: the mailbox cannot be confirmed), `unknown` (no clear answer); empty when the option is off |
| `previousAddresses` | **Address history**: `address`, `street`, `city`, `state`, `zip`, `county`, `recorded` (`June 2025`) |
| `relatives`, `associates` | **Relatives and associates**: `name`, `age`, `born`, `id`, `url` of each |
| `possibleSpouse`, `maritalStatus` | the person the records say they are likely married to; the site's sentence on marriage records |
| `property`, `isAbsentee` | **Property of the home**: `bedrooms`, `bathrooms`, `squareFeet`, `lotSquareFeet`, `yearBuilt`, `estimatedValue`, `estimatedEquity`, `lastSaleAmount`, `lastSaleDate`, `occupancyType`, `ownershipType`, `landUse`, `propertyClass`, `subdivision` (amounts in USD); `true` when the owner does not live there |
| `employment`, `education`, `businesses` | **Work and education**: employer and title, schools and degrees, linked companies with role and since when |
| `searchType`, `searchInput`, `inputId`, `targetName` | **Search and match**: `name`, `address`, `phone`, `email` or `url`; the search as you gave it; your own id; the name looked for |
| `nameMatch`, `matchScore` | `matched` (first and last names match), `fallback` (nobody matched: first person listed) or `none` (no name to compare); 0-100 |
| `searchUrl`, `scrapedAt` | the results page the person was found on, ISO timestamp |

### 💡 Tips

#### How to get the owner of an address

Put the owner's name after the address: `641 NW 59th Ave; Miami, FL 33126 | Janette Suarez`. The person whose first AND last names match comes first — and when the owner does not live there (a rented house), the owner is often listed as a relative of the residents: that person is found and returned too (without **Full person report**, with their name and page only: tick it for their phones, emails and address). Tick **Only people whose name matches** to get nothing rather than a resident when the owner cannot be found. Without a name, an address returns its residents, newest first.

#### How to reduce costs

Keep **Max people per search** at 1 when you want one person per search, and use **Only new people** for lists you run again (a person already delivered is never read nor charged twice). Filters drop a person before it is saved: a person dropped on the search result (name, age, words, name match) costs only the filter fee ($0.35 per 1,000); one dropped for lack of a phone or an email costs its full report and $0.20 per 1,000 — still less than a person you keep. **Full person report** is off by default: turn it on only when you need the phones and emails — it adds the full-report fee to each person.

#### Several searches in one run

Fill any mix of **Names**, **Addresses**, **Phone numbers**, **Emails** (up to 1,000 lines per list), **People (structured)**, a **CSV file URL** and **Start URLs**: up to 5,000 searches per run. A line that cannot be searched (an address without its state, a 7-digit phone number) is skipped with a warning in the log — one bad line does not stop the run. The same address (or phone, or email) given twice with two different names — two owners of one house — is searched once, for the first name, and the second line is listed as skipped: raise **Max people per search** to get the other people of that search too. A person found by several searches is saved — and charged — once, with the first search that found them.

#### Monitoring: only the new people

Tick **Only new people** (`onlyNew`) and schedule the Actor on the same list. The first run returns everything; each later run skips the people already delivered: they are not saved nor charged, and their report is not even opened (the search itself is still run and charged). The memory lives in a named key-value store of your account (`people-skip-trace-scraper-seen`, up to 150,000 people per key) and is only updated with people that really reached the dataset, so a failed run never hides anyone. Give each schedule its own `stateKey`, and tick `resetState` once to start over.

### 🔌 Integrations and API

Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable, HubSpot…). The dataset can be fetched as JSON or CSV from any tool; `inputId` brings your own record id back with each person.

### 🤖 Use with AI agents (MCP)

AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the [Apify MCP server](https://mcp.apify.com), billed to their Apify account like any run. It returns one item per person found. Actor id: `nice_dev/people-skip-trace-scraper`; MCP server with this Actor only: `https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/people-skip-trace-scraper`.

Smallest input, for a cheap first call (the search result only: name, age, city, relatives):

```json
{
    "name": ["Janette Suarez; Miami, FL"],
    "maxItems": 1
}
```

For phone numbers and emails, add the full report:

```json
{
    "name": ["Janette Suarez; Miami, FL"],
    "maxItems": 1,
    "extractDetails": true
}
```

Key output fields: `fullName`, `age`, `city`, `state`, `relatives`, `nameMatch`; with the full report, `currentAddress`, `bestPhone`, `phones`, `emails`.

Cost on Gold: $2.23 per 1,000 searches, $2.13 per 1,000 people and $1.94 per 1,000 full reports (Free plan: $6.36, $6.09, $5.55), plus $0.0009 per run (see the pricing section above). Cap each call with `maxItems` and, through the API, with the run option `maxTotalChargeUsd`.

### ❓ FAQ

#### Is it legal to skip trace people with this Actor?

The Actor only reads what FastPeopleSearch and CyberBackgroundChecks show publicly to any anonymous visitor: public records. It logs in to nothing and needs no account. The results are personal data: store and use them only with a legitimate reason, under the privacy laws that apply to you (GDPR, CCPA and the other US state laws). You are responsible for using the data in compliance with the sites' Terms of Use and applicable law, in particular:

- **FCRA**: this is not a consumer reporting agency. Never use the results to decide on credit, employment, tenant screening, insurance or any other purpose covered by the Fair Credit Reporting Act.
- **TCPA and Do Not Call**: calling or texting a mobile number with an autodialer or a prerecorded message needs the person's consent; check the numbers against the National Do Not Call Registry before any marketing call. The Actor does not flag them.
- **Data broker laws**: reselling data about people you have no direct relationship with can require a registration (California, Vermont, Texas, Oregon).
- **Daniel's Law (New Jersey)** and similar laws: remove the people who ask for it (judges, law enforcement officers…) within the legal delay.

This Actor is not affiliated with FastPeopleSearch or CyberBackgroundChecks.

#### Am I charged for a search that finds nobody?

Yes, the search fee only (`people-search`): the sites are read to find out that nobody matches. No person, no report and no row are charged. The `SEARCH_STATS` record of the run lists every search with the number of people it saved (0 = nobody found).

#### Does it need a login or an account on the sites?

No. Nothing to set up either: leave **Proxy configuration** as it is, it is included in the price.

#### Is the data safe to open in Excel or to show on a web page?

Phone numbers start with `(` or `+` (every `e164` number does, `+1…`) and a few names or addresses start with a digit: Excel and Google Sheets may read a CSV cell that begins with `+`, `-`, `=` or `@` as a formula, and turn a ZIP code such as `02111` into a number without its leading zero. The Actor leaves the values as they are, so that the JSON and the API give the real value: when you open a CSV, import the phone and ZIP columns as text. On a web page, every link (`url`, `currentAddressUrl`, the links of relatives, associates and the spouse) is an `http://` or `https://` URL, or empty — never `javascript:`, never a quote (an apostrophe is written `%27`, the same page); escape every other field like any text written by a stranger.

#### Why are the phone numbers and emails empty?

**Full person report** is off by default: without it, a person comes with what the search result lists (name, age, city, relatives' names, past cities), never emails. Tick it (`"extractDetails": true`) for every phone number and email; **Only people with a phone number**, **Only people with an email** and **Check that emails exist** need it too, and the run log says so when they are ticked without it.

#### Can it check that the emails still work?

Yes, with **Check that emails exist** (off by default, priced separately) and **Full person report** on. Each of the first 5 emails of a report is checked with its email provider; no email is ever sent. `valid` means the provider confirms the mailbox exists on that day (not that someone reads it): Gmail and the other providers that answer. `invalid` means the domain takes no email at all, or the provider says the mailbox does not exist. Some large providers (Yahoo, AOL, Outlook, Comcast) do not say, or accept any address: their emails come back `unknown` or `accept-all`, and those answers are free — you pay only for `valid` and `invalid`. Phone numbers are not checked: the sites say nothing about a line being active.

#### Known limitations

- Each phone number comes with the date it was **first** reported, not the last one; the sites say nothing about a number being disconnected, on the Do Not Call list or tied to a litigator.
- A deceased person is still returned (an address search lists past residents too): filter on `isDeceased`.
- An email or a phone number shared by several people (a family) returns all of them when **Max people per search** is above 1; with 1, the first one listed, unless you add the name you want after the line.
- Names are matched on first and last names with common nicknames (Bill / William); a very rare nickname is not recognised.
- `onlyNew` remembers people, not their details: a person whose phone numbers changed is not returned again.
- Two runs sharing the same `stateKey` at the same time may both return the same new person.

**A run that reaches its timeout** stops itself about 45 seconds before it: no new page is asked, the people it read are saved and, with `onlyNew`, remembered, and the run ends *Succeeded* with "Stopped before the run's timeout". At about 13 people a minute with the full report, a one-hour timeout holds roughly 750 people: resurrect the run to go on from there, or give a big list a longer timeout (Run options).

**A run the platform stops without warning** (out of memory)

- Resurrect it: it goes on from where it stood at most a minute before the stop, and the people already saved are skipped: none is delivered or charged twice, and `maxItems` still counts them. A person found in the last minute before the stop and not yet written may be missing: run that line again.
- With `onlyNew`, the memory is saved once a minute: resurrect the stopped run and the people it had saved meanwhile join the memory; leave it stopped for good, and the next run may return up to a minute of them once more.

#### Something doesn't work?

The last line of the log counts the people saved, filtered out and no longer on the site, and the requests that failed after every retry. Those requests are listed, with the reason, in the `FAILED_REQUESTS` record of the run's key-value store. The `SEARCH_STATS` record lists every search with the number of people it saved (0 = nobody found) and the lines that were skipped, with the reason. A run that saved nothing and had failed requests fails, and its last message gives the cause.

If the sites change their pages, you are told instead of paying for blank rows. If the first 20 people read all lack their city (read on the results page) or — with the full report — their relatives or their phones, the run saves nothing more, stops and fails, and its last message names the missing field: at most those first people are charged. A shorter run is checked at its end, from 5 people: it fails the same way, with the people it saved. A results page that announces people none of whom can be read fails its search instead of passing for "nobody found".

### 🛟 Support

Open an issue in the **Issues** tab with a link to your run: the run log and the `FAILED_REQUESTS` and `SEARCH_STATS` records of the key-value store show exactly which searches failed and why.

# Actor input Schema

## `name` (type: `array`):

One person per line: `Full name; City, ST` or `Full name; ST` (e.g. `Janette Suarez; Miami, FL`). A ZIP code may follow the state. The city and state make the match much better.

## `street_citystatezip` (type: `array`):

One address per line: `Street; City, ST ZIP` (e.g. `641 NW 59th Ave; Miami, FL 33126`). Returns the people linked to the address, newest first. Add `| Full name` at the end to put that person first (e.g. the owner): `641 NW 59th Ave; Miami, FL 33126 | Janette Suarez`.

## `phone_number` (type: `array`):

Reverse phone lookup, one US number per line, any format (`(786) 523-6332`, `7865236332`, `+1 786 523 6332`). Add `| Full name` to put that person first.

## `email` (type: `array`):

Reverse email lookup, one email per line. Add `| Full name` to put that person first.

## `people` (type: `array`):

For CRMs and automations: a JSON list of objects with any of `firstName`, `lastName`, `street`, `city`, `state`, `zip`, `phone`, `email` and your own `id` (copied to the result as `inputId`). Each object is one search: by address when a street is given, else by phone, else by email, else by name.

## `csvUrl` (type: `string`):

Link to a CSV file (e.g. a Google Sheets `…/export?format=csv` link) with a header row. Recognised columns: `name` or `first name` + `last name`, `street` / `address`, `city`, `state`, `zip`, `phone`, `email`, `id`. Each row is one search, like **People (structured)**.

## `startUrls` (type: `array`):

FastPeopleSearch search pages (`/name/…`, `/address/…`, phone pages) or person pages (`…_id_G-…`), and CyberBackgroundChecks email pages (`/email/…`). A person page is read in full and charged as a full report, even with **Full person report** off. Max 1 000 URLs.

## `maxItems` (type: `integer`):

Maximum number of people to save for the whole run (after filters). 0 = no limit.

## `maxItemsPerQuery` (type: `integer`):

People saved for EACH search. 1 = the best match only (the person whose name matches, else the first one listed). Raise it to get every resident of an address or every namesake. 0 = no per-search cap.

## `extractDetails` (type: `boolean`):

Off by default. Turn it on for each person's phone numbers (type, carrier, first reported), emails, past addresses with dates, relatives and associates with ages, property, employment and businesses: the Actor opens each person's page, charged per report (see Pricing). Off = what the search result lists: name, age, city, relatives' names, past cities (and the phones an email search lists), never emails. **Only people with a phone number**, **Only people with an email** and **Check that emails exist** need it.

## `verifyEmails` (type: `boolean`):

Check each of the first 5 emails of a report with its email provider (no email is ever sent). Adds `emailChecks` and `email1Status`-`email5Status`: `valid` (the email provider confirms the mailbox exists: Gmail and the other providers that answer), `invalid` (the domain takes no email, or the provider says the mailbox does not exist), `accept-all` (the domain accepts any address: the mailbox cannot be confirmed), `unknown` (no clear answer: several large providers such as Yahoo, AOL or Outlook do not say). Priced separately, per `valid` or `invalid` answer only: `accept-all` and `unknown` are free. Needs **Full person report**: ignored when it is off.

## `requireNameMatch` (type: `boolean`):

With a name to look for (a name search, or `| Full name` after an address, phone or email): save only the people whose first and last names match it (nicknames and middle names tolerated). Off = when nobody matches, the first person listed is saved and marked `nameMatch: fallback`.

## `requirePhone` (type: `boolean`):

Drop the people without any phone number (needs **Full person report**: ignored when it is off).

## `requireEmail` (type: `boolean`):

Drop the people without any email (needs **Full person report**: ignored when it is off).

## `minAge` (type: `integer`):

Drop the people younger than this. People whose age is not known are kept.

## `maxAge` (type: `integer`):

Drop the people older than this. People whose age is not known are kept.

## `excludeKeywords` (type: `array`):

Drop the people whose name contains one of these words (case and accents ignored), e.g. `LLC`, `Trust`.

## `onlyNew` (type: `boolean`):

Skip the people that a previous run (same **Memory key**) already delivered: they are not saved and not charged, and their page is not even opened. First run = everything is new.

## `stateKey` (type: `string`):

Name of the memory used by **Only new people**. Give each schedule / task its own key (e.g. `miami-owners`) so that they do not share their memory. Letters, digits, `-` and `_`.

## `resetState` (type: `boolean`):

Forget everything remembered under this **Memory key** before the run: this run returns (and charges) every person again. Untick it afterwards.

## `proxyConfiguration` (type: `object`):

Keep the default (Apify Proxy): the access to the sites is included in the price. Your own proxies (custom proxy URLs) are used instead when you give them. The residential Apify proxy is not available in this Actor.

## `maxConcurrency` (type: `integer`):

Maximum number of pages read in parallel.

## `maxRequestsPerMinute` (type: `integer`):

Most page requests in any 60 seconds, search pages and person pages counted. A budget, not an even pace (spread them with the minimum delay below). Lower it if the log shows many refused pages.

## `minRequestIntervalMs` (type: `integer`):

Smallest gap between two requests, in milliseconds. Unlike the per-minute rate, this spreads the requests evenly. 0 = no gap.

## `maxRequestRetries` (type: `integer`):

Retries per page before it is marked as failed.

## `debugLog` (type: `boolean`):

Include debug messages in the run log.

## Actor input object example

```json
{
  "name": [
    "Janette Suarez; Miami, FL"
  ],
  "street_citystatezip": [],
  "phone_number": [],
  "email": [],
  "people": [],
  "startUrls": [],
  "maxItems": 100,
  "maxItemsPerQuery": 1,
  "extractDetails": false,
  "verifyEmails": false,
  "requireNameMatch": false,
  "requirePhone": false,
  "requireEmail": false,
  "excludeKeywords": [],
  "onlyNew": false,
  "stateKey": "default",
  "resetState": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 5,
  "maxRequestsPerMinute": 120,
  "minRequestIntervalMs": 0,
  "maxRequestRetries": 5,
  "debugLog": false
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `searchStats` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "name": [
        "Janette Suarez; Miami, FL"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("nice_dev/people-skip-trace-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "name": ["Janette Suarez; Miami, FL"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("nice_dev/people-skip-trace-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "name": [
    "Janette Suarez; Miami, FL"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call nice_dev/people-skip-trace-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/people-skip-trace-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/PwpeDOhuwGqgS1Xs9/builds/9ns69V6ebkjsbPZTR/openapi.json
