# Changelog of Skip Trace API — Phone, Email & Address Lookup (`mu0i/skip-tracing-api`) Actor

- **URL**: https://apify.com/mu0i/skip-tracing-api/changelog.md
- **Full Actor documentation**: https://apify.com/mu0i/skip-tracing-api.md

## Changelog

### 0.1 update — 2026-10-23

Richer addresses, at no extra cost per row — the data was already in the responses we fetch and was
being discarded before it reached you:

- Addresses now carry `zip4` (the +4 half of ZIP+4), `latitude`, `longitude` and `deliverable`
  (mailable per the source's own address validation). Measured fill rates on the main source: ZIP+4
  on 201 of 217 addresses, coordinates on 199, deliverable on 185.
- Each address carries the `phones` tied to **that** address. Every one of those numbers is already
  in the row's `phones` list, so this is not more numbers — it tells you which number belongs to
  which address, so a lead with four numbers and three past addresses stops being a guess.
- `flatOutput` gains `ZIP+4`, `Latitude`, `Longitude` and `Deliverable` columns, appended after the
  existing ones. `Postal Code` is still the 5-digit ZIP, and no existing column changed, so a sheet,
  Zapier zap or CRM mapping already in use keeps working untouched.
- `deliverable: false` does **not** make a row free. The sources state it on most but not all
  addresses, so treating "absent" as undeliverable would give away every address a source simply
  never validated — and a street found for a named person is still evidence about where they were
  even when the Postal Service will not deliver there. Billing is unchanged: a row costs the same as
  before, and now carries more.

### 0.1 update — 2026-10-17

CSV / Google Sheet input fixes:

- A street containing the city's name ("12 Springfield Rd" in Springfield) keeps its city, state and ZIP.
- Name + City/State columns (no address) search the name with that location.
- CSVs saved with `;` separators (Excel in many locales) are read, and commas inside quoted cells no
  longer confuse delimiter detection.
- Business owners ("ACME, LLC") are not reordered as "Last, First"; a `|` inside a cell no longer splits
  the person filter.
- A cell with several emails or phones ("a@x.com; b@y.com") searches the first instead of failing.
- Repeated columns of one kind (`Phone`, `Mobile`) use the first one filled in on each row.
- A headerless list whose lines contain commas is read line by line instead of being rejected.
- Signed-in Sheet links (`/u/0/`) are converted, and the tab on screen (`#gid`) wins over a stale `?gid`.
- Large lists no longer crash the parser; a timeout or dropped connection while downloading is retried and
  reported plainly; links to private or local network addresses are refused.
- Rows with no name, address, phone or email are counted in the status message.

Other fixes:

- A list over 1,000 searches says in the status message that only the first 1,000 ran.
- `absenteeOwner` is no longer set wrongly when one street is written two ways ("Fifth Avenue" / "5th Ave",
  "Saint" / "St"), and is left unset (not "owner-occupied") when the search gives no city or ZIP to compare.

### 0.1 — 2026-10

First public release.

- Search by name (with optional city/state or ZIP), street address, phone number or email.
- List input: up to 1,000 searches per run, all four types mixed, run in parallel. A `| Full Name`
  suffix on any entry keeps only that person, checked against everyone the search finds (not just the
  first few). A miss is a free `not_found` whose `message` says how many others were found;
  `fallbackWhenNoMatch: true` returns the first person instead, flagged `nameMatch: false`.
- Every row carries `input`, `searchType` and `status` (`found` / `not_found` / `invalid_input` /
  `error` / `skipped`). Only `found` rows that name a person AND give a phone, an email or a street
  address are charged; rows with only a city, state or ZIP, or a phone with no person behind it, are
  delivered free.
- Returns the single best-corroborated person per search by default (`maxResults: 1`), so a list
  of N searches bills at most N results unless you ask for more.
- Respects the run's maximum cost: stops cleanly at the limit and marks the remaining searches
  `skipped`. Resumes after a platform restart without re-running or re-charging finished searches.
  A hard ceiling of searches × `maxResults` billed results per run is enforced in the Actor itself.
- Free-plan runs try at most 10 searches (and return at most 3 results). A run whose first 100 searches
  find nobody stops and marks the rest `skipped` with a message about the input format.
- Misspelled or alternative input field names (`street_citystatzip`, `addresses`, `phones`) are read
  as the field meant, unknown fields are reported, and addresses, phones and emails pasted into the
  `name` list are searched as what they are. Every correction appears in the run's status message.
- CSV / Google Sheet input (`csvUrl`): paste a Google Sheet share link (or a Drive, Dropbox or plain
  CSV link) and each row becomes one search. Columns are mapped by header (`Owner Name`, `Owner First` +
  `Last Name`, `Property Address`, split `City`/`State`/`Zip`, `Last, First` names, full state names,
  ZIPs missing a leading zero, title rows above the header). For an address list with owner names, the
  name pinpoints the resident at each address. Every row from the file carries `csvRow`, its line
  number in the sheet. Duplicate entries are searched once. A sheet that can't be read (private, wrong
  link, Excel file) ends the run with a plain explanation, never a failure.
- `bestPhone` / `bestEmail` on every found row: the one number and email to try first (most recent
  wireless), at the top level so CSV exports are usable without opening the nested arrays.
- `absenteeOwner` on address searches: flags whether the owner lives at the property or elsewhere.
- Each lookup checks several independent people-search databases live, and merges records for the same
  person into one row.
- Phones with line type, carrier and first/last-seen dates; emails; current and previous addresses with
  county; relatives and associates with ages.
- `matchBasis` on every row shows how strongly it is corroborated across independent sources.
- Father/son (Jr/Sr) and same-name people are kept apart. Records are merged on a shared street, or
  the same birth year and town (city or ZIP), never on a shared state alone; and two records the
  same database lists as different people are never merged.
- Ranking: a town, ZIP or state named in a search puts people there first; the living rank above the
  deceased; a name search never returns a record with a different surname.
- Relatives and associates: family (same surname) first, at most 12 — not the whole network one source
  lists.
- `flatOutput`: optional spreadsheet column layout (`Phone-1` … `Phone-5` with Type / Provider /
  First and Last Reported, `Email-1` … `Email-5`, `Lives in`, `Previous Addresses`, `Relatives`,
  `Associates`) matching other skip trace Actors, on top of the regular fields.
- Duplicate copies of one record no longer appear as separate people, and `matchBasis` only reports
  agreement between independent databases.
- A city, state or ZIP in a name search is now honored by every source, and a name search only returns
  people whose first name agrees with the one searched (nicknames and initials count: Jim / James, J /
  James). Before, a search like "Maria Garcia; Houston, TX" could return same-name people from other
  states as its top, billed result.
