← the lab · the atelier

Sheet 120 · business tools

LinkedIn contacts into our CRM

A web app that loads a LinkedIn data export into our Attio CRM, matching every person before it creates anyone and never overwriting a field that is already filled.

What it is

LinkedIn exportconnections andmessagesSame email?match: fill the gaps;else next checkSame profile link?same ruleSame name andcompany?no match: a new personFill empty fieldsnothing already thereis overwrittenNew personadded to theconnections listmatchno matchLinkedInexportconnections andmessagesSame email?match: fill thegaps; else nextcheckSame profilelink?same ruleSame name andcompany?no match: a newpersonFill emptyfieldsnothing alreadythere isoverwrittenNew personadded to theconnectionslistmatchno match
FIG. 1One person from the export. Each check runs only if the one before found nothing. A match at any of the three leads to the same place: the existing record keeps its data and only gains what was missing.
Source: linkedin-data-connector README.md and src/lib/matching/matcher.ts, HEAD 8acf056

LinkedIn lets you download your data as a ZIP. This app reads two files from it, the connections and the messages, and loads them into Attio, the CRM we used at CogniScope. It creates companies by name, people with their job title and the date we connected, a list of all connections, and every message as a record linked to its person. A "connected with" field keeps the names of everyone on the team who knows that person, so each of us could import our own export.

Before it creates anyone, it looks for a match: by email first, then by LinkedIn profile link, then by name and company. A match only gets its empty fields filled, so running it again on a newer export is safe.

What happened

I wrote the first version in late February 2026, 37 of the 49 commits. The commit log reads like a list of what real exports do: conversation titles that newer exports leave empty, names that differ between the two files, imports that timed out until the work went in chunks. One commit replaced 836 single lookups with one bulk fetch of every person. Two small Python scripts then found the duplicates already in the CRM and merged each group into the record with the most data.

Barış Ülgen moved the tests to Vitest, cleaned up the code and fixed the list and company imports. I have no record of how many people the final import brought in.

← Bulk AI runs over a spreadsheet · all lab sheets · Text labelling app →